home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 751-760 / 756 / popupmenu / source / popup.a < prev    next >
Text File  |  1995-03-18  |  77KB  |  3,178 lines

  1.         include     "All.i"
  2.         include     "exec/types.i"
  3.         include     "PopUp.i"
  4.  
  5.         xref        PopUpSemaphore
  6.         xref        @QueTimer
  7.         xref        @AbortTimer
  8.         xdef        @PopUpMenu
  9.  
  10. VBORDERSIZE    equ        4          ; Vertical border (pixels)
  11. HBORDERSIZE    equ        2          ; Horizontal border (pixels)
  12. OVERLAP     equ        8          ; Overlap itemwindow->menuwindow (pixels)
  13.  
  14. ITEMWINDOW    equ        0
  15. SUBWINDOW    equ        WORD_MAX
  16.  
  17. ITEMFILL    equ        0
  18. HIGHLIGHTON    equ        1
  19. HIGHLIGHTOFF    equ        0
  20.  
  21.         section     text,code
  22. **********************************************
  23. * BOOL PopUpMenu(VOID)                       *
  24. *                         *
  25. * Input:                     *
  26. *   none                     *
  27. * Output:                     *
  28. *   return    FALSE if MENU_UP will come   *
  29. **********************************************
  30. @PopUpMenu:    movem.l     D2-D5/A2/A3/A6,-(SP)
  31.  
  32. ;   Get the semaphore
  33.         lea        PopUpSemaphore(PC),A0
  34.         move.l        _ExecBase(A4),A6
  35.         libcall     ObtainSemaphore   ; Exclusive lock
  36.  
  37. ;   Set returncode to FALSE
  38.         moveq.l     #FALSE,D0
  39.         move.w        D0,-(SP)
  40.  
  41. ;   Be sure the window is still open
  42.         call        FindWindow
  43.         tst.w        D0
  44.         beq        Abort2    ; Quick abort
  45.  
  46. ;   Lock the screen
  47.         move.l        _Screen(A4),A3
  48.         lea        sc_LayerInfo(A3),A2
  49.         move.l        A2,A0
  50.         move.l        _LayersBase(A4),A6
  51.         libcall     LockLayers
  52.  
  53. *********************
  54. * A2 = LayerInfo    *
  55. * A3 = Screen        *
  56. * A6 = LayersBase   *
  57. *********************
  58. ;   Clear the global variables used
  59.         lea        _ClearStart(A4),A0
  60.         move.w        #(_ClearEnd-_ClearStart)/2-1,D0
  61.         moveq.l     #0,D4    ; Use D4 (no need to clear it later)
  62. 1$        move.w        D4,(A0)+
  63.         dbra        D0,1$
  64.  
  65. ;   No selections done so far.
  66.         move.w        D0,_FirstSelected(A4)  ; MENUNULL
  67.  
  68. ;   if screen is LORES use larger "Amiga-key" symbol
  69.         btst        #V_HIRES_B0,sc_ViewPort+vp_Modes(A3)
  70.         bne        2$
  71.         move.w        #TRUE,_ScreenType(A4)
  72.  
  73. ;   Initialize our rastport
  74. 2$        lea        _Rp(A4),A1
  75.         move.l        _GfxBase(A4),A6
  76.         libcall     InitRastPort
  77.  
  78. ;   Set default font to screen font
  79.         lea        _Rp(A4),A1
  80.         move.l        sc_RastPort+rp_Font(A3),A0
  81.         libcall     SetFont
  82.  
  83. ;   Find the with of the default command key
  84.         lea        -te_SIZEOF(SP),SP
  85.         move.l        sc_RastPort+rp_Font(A3),A0
  86.         move.l        SP,A1
  87.         libcall     FontExtent
  88.         move.w        te_Extent+ra_MaxX(SP),_CommKeyWidth(A4)
  89.         lea        te_SIZEOF(SP),SP
  90.  
  91. ;   find the height of menu texts
  92.         move.b        sc_BarHeight(A3),_MenuTextHeight+1(A4)
  93.  
  94. ;   We use the screen's bitmap
  95.         lea        sc_BitMap(A3),A0
  96.         move.l        A0,_Rp+rp_BitMap(A4)
  97.  
  98. ;   Use the window pens when drawing the menus
  99.         move.l        _ActiveWindow(A4),A0
  100.         move.w        wd_DetailPen(A0),_DetailPen(A4)   ; move both pens
  101.  
  102. ;   Get the menus  [ use D3 here, see below ]
  103.         move.l        wd_MenuStrip(A0),D3
  104.         move.l        D3,_Menus(A4)
  105.         beq        NoMenus       ; OOPS!
  106.  
  107. ;   Set MENUSTATE flag
  108.         bset        #WFLG_MENUSTATE_B2,wd_Flags+2(A0)
  109.  
  110. ;   if we have used these menus before start at last selection
  111. ;   D3 = Menus
  112.         lea        _LastMenus(A4),A0
  113.         move.l        D3,A1           ; A1 = What to look for
  114. ;[not needed]    moveq.l     #0,D4           ; D4 = Selected [ nothing yet ]
  115.         moveq.l     #MAXREMEMBER-1,D0
  116.  
  117. 3$        move.l        llm_Menus(A0),D1
  118.         move.w        llm_Num(A0),D2
  119.         move.l        D3,llm_Menus(A0)
  120.         move.w        D4,llm_Num(A0)
  121.         exg.l        D1,D3
  122.         exg.l        D2,D4
  123.  
  124.         addq.l        #llm_SIZEOF,A0
  125.         cmp.l        A1,D3     ; Found the right one ?
  126.         dbeq        D0,3$
  127.  
  128.         beq        4$         ; Found one
  129.  
  130.         moveq.l     #1,D4     ; not used before -> start at top
  131.  
  132. 4$        move.w        D4,_LastMenus+llm_Num(A4)
  133.         move.w        D4,D0
  134.         beq        OpenMenus
  135.  
  136. ;   calculate position in menuwindow.
  137.         subq.w        #1,D0
  138.         mulu.w        _MenuTextHeight(A4),D0
  139.  
  140. ;   Open the menus.
  141. OpenMenus:    call        OpenMenuWindow
  142.         tst.w        D0
  143.         beq        NoMenus
  144.  
  145. ********************
  146. * A2 = LayerInfo   *
  147. * A3 = Screen
  148. * A6 = GfxBase       *
  149. ********************
  150. ;   Abort the timer if it is running.
  151.         call        AbortTimer
  152.  
  153. ;   Start up a new timer.
  154.         moveq.l     #INPUT_DEVICE_WAIT,D0
  155.         call        QueTimer
  156.  
  157. ;   Combine the signals we use
  158.         move.l        _TimerSigMask(A4),D3
  159.         or.l        _CxHandlerData+ssd_MouseMovedSig+ssi_Mask(A4),D3
  160.         or.l        _CxHandlerData+ssd_MenuUpSig+ssi_Mask(A4),D3
  161.         or.l        _CxHandlerData+ssd_SelectUpSig+ssi_Mask(A4),D3
  162.         or.l        _CxHandlerData+ssd_SelectDownSig+ssi_Mask(A4),D3
  163.  
  164. ;   Clear local variables
  165.         moveq.l     #FALSE,D2    ; D2 = Waiting
  166.  
  167.         moveq.l     #FALSE,D4    ; D4 = SelDown
  168.  
  169. *****************************************
  170. * D2 = Waiting           A2 = LayerInfo    *
  171. * D3 = AllSig                *
  172. * D4 = SelDown                *
  173. *****************************************
  174. ;   SignalBits = Wait(MouseMovedSig | MenuUpSig | SelectUpSig | SelectDownSig | TimerSig);
  175. WaitNextSig:    move.l        D3,D0
  176.         move.l        _ExecBase(A4),A6
  177.         libcall     Wait
  178.  
  179.         move.l        D0,D5
  180.  
  181. *****************************************
  182. * D2 = Waiting           A2 = LayerInfo    *
  183. * D3 = AllSig                *
  184. * D4 = SelDown           A6 = SysBase    *
  185. * D5 = SignalBits            *
  186. *****************************************
  187. ;   Inputhandler alive ?
  188.         and.l        _CxHandlerData+ssd_MouseMovedSig+ssi_Mask(A4),D0
  189.         beq        SelectDown
  190.  
  191. ;   Clear waiting flag
  192.         moveq.l     #FALSE,D2
  193.  
  194. ;   Get the mouse coordinates
  195.         move.w        sc_MouseX(A3),D0
  196.         move.w        sc_MouseY(A3),D1
  197.         cmp.w        _MouseX(A4),D0
  198.         bne        MouseMoved
  199.         cmp.w        _MouseY(A4),D1
  200.         beq        SelectDown          ; mouse not moved
  201.  
  202. ;   remember    the new mouse coordinates
  203. MouseMoved:    move.w        D0,_MouseX(A4)
  204.         move.w        D1,_MouseY(A4)
  205.  
  206. ;   if CLICKMENUS we should only do selection if selectbutton is pressed
  207.         btst        #CLICKMENUS_B0,_CxHandlerData+ssd_Options(A4)
  208.         beq        1$
  209.  
  210.         tst.w        D4          ; SelectButton down
  211.         beq        SelectDown      ; No
  212.  
  213.         call        SelectItem
  214.         bra        SelectDown
  215.  
  216. ;   do selection
  217. 1$        call        SelectItem
  218.         tst.w        D0
  219.         beq        SelectDown      ; nothing selected
  220.  
  221. ;   if selectbutton is down we are drag-selecting
  222.         tst.w        D4
  223.         beq        SelectDown
  224.  
  225. ;   is it possible to select the item ?
  226.         call        CheckSelected
  227.         tst.l        D0
  228.         beq        SelectDown         ; No
  229.  
  230. ;   rememember that this item is drag selected (set MENUTOGGLED flag)
  231.         move.l        D0,A0
  232.         bset        #MENUTOGGLED_B0,mi_Flags(A0)
  233.  
  234. *****************************************
  235. * D2 = Waiting           A2 = LayerInfo    *
  236. * D3 = AllSig                *
  237. * D4 = SelDown           A6 = SysBase    *
  238. * D5 = SignalBits            *
  239. *****************************************
  240. ;   user pressed the selectbutton ?
  241. SelectDown:    move.l        D5,D0
  242.         and.l        _CxHandlerData+ssd_SelectDownSig+ssi_Mask(A4),D0
  243.         beq        MenuUp    ; No
  244.  
  245. ;   if clickmenus just do selection
  246.         btst        #CLICKMENUS_B0,_CxHandlerData+ssd_Options(A4)
  247.         beq        1$
  248.  
  249.         call        SelectItem
  250.         bra        2$
  251.  
  252. ;   otherwise start drag-selection
  253. 1$        call        CheckSelected
  254.  
  255. ;   remember where we started the drag-select
  256.         move.l        D0,_FirstDrag(A4)
  257.         beq        MenuUp    ; nothing selected
  258.  
  259.         move.l        D0,A0
  260.         bset        #MENUTOGGLED_B0,mi_Flags(A0)
  261.  
  262. ;   SelDown = TRUE
  263. 2$        moveq.l     #TRUE,D4
  264.  
  265. *****************************************
  266. * D2 = Waiting           A2 = LayerInfo    *
  267. * D3 = AllSig                *
  268. * D4 = SelDown           A6 = SysBase    *
  269. * D5 = SignalBits            *
  270. *****************************************
  271. ;   User released the menu button ?
  272. MenuUp:     move.l        D5,D0
  273.         and.l        _CxHandlerData+ssd_MenuUpSig+ssi_Mask(A4),D0
  274.         beq        SelectUp     ; No
  275.  
  276. ;   Set new returncode
  277.         moveq.l     #TRUE,D0
  278.         move.w        D0,(SP)
  279.  
  280. ;   if select-button is pressed, end the drag-selection
  281.         tst.w        D4
  282.         beq        1$
  283.  
  284.         call        ClearToggle
  285.  
  286.         bra        NoMoreSel
  287.  
  288. ;   do the last selection
  289. 1$        call        CheckSelected
  290.  
  291.         bra        NoMoreSel
  292.  
  293. *****************************************
  294. * D2 = Waiting           A2 = LayerInfo    *
  295. * D3 = AllSig                *
  296. * D4 = SelDown           A6 = SysBase    *
  297. * D5 = SignalBits            *
  298. *****************************************
  299. *   Select-button released
  300. SelectUp:    move.l        D5,D0
  301.         and.l        _CxHandlerData+ssd_SelectUpSig+ssi_Mask(A4),D0
  302.         beq        Timer     ; No
  303.  
  304.         moveq.l     #FALSE,D4      ; seldown
  305.  
  306. ;   If CLICKMENUS just do selection
  307.         btst        #CLICKMENUS_B0,_CxHandlerData+ssd_Options(A4)
  308.         beq        1$
  309.  
  310.         call        CheckSelected
  311.         tst.l        D0
  312.         beq        Timer
  313.  
  314.         moveq.l     #TRUE,D1      ; No MENU_UP will come
  315.         move.w        D1,(SP)
  316.  
  317. ;   Disable MENU_UP
  318.         bclr        #MENUS_ON_B,_CxHandlerData+ssd_Flags(A4)
  319.         bra        NoMoreSel      ; end selection
  320.  
  321. ;   end the drag-select
  322. 1$        call        ClearToggle
  323.  
  324. ;*****************************************
  325. ;* D2 = Waiting     A2 = LayerInfo     *
  326. ;* D3 = AllSig                 *
  327. ;* D4 = SelDown     A6 = SysBase     *
  328. ;* D5 = SignalBits             *
  329. ;*****************************************
  330. ;   Timer finished ?
  331. Timer:        move.l        D5,D0
  332.         and.l        _TimerSigMask(A4),D0
  333.         beq        NextSig     ; No
  334.  
  335. ;   Have something else happened since last timer event ?
  336.         tst.w        D2
  337.         beq        NoLockup     ; Yes
  338.  
  339. ;   The input.device has stopped.
  340. ;   Remove everything from the screen.
  341.         lea        _SubWindow(A4),A0
  342.         call        SwapBits
  343.         lea        _ItemWindow(A4),A0
  344.         call        SwapBits
  345.         lea        _MenuWindow(A4),A0
  346.         call        SwapBits
  347.  
  348. ;   Unlock the screen.
  349.         move.l        A2,A0
  350.         move.l        _LayersBase(A4),A6
  351.         libcall     UnlockLayers
  352.  
  353. ;   Wait for the input.device to start again
  354.         move.l        D3,D0      ; Any reply will do
  355.         move.l        _ExecBase(A4),A6
  356.         libcall     Wait
  357.  
  358. ;   Is the screen and window still open ?
  359.         call        FindWindow
  360.         tst.w        D0
  361.         bne        OKToLock
  362.  
  363. ;   The window is gone!!!  Abort.
  364.         lea        _SubWindow(A4),A0
  365.         call        RemoveBitMap
  366.         lea        _ItemWindow(A4),A0
  367.         call        RemoveBitMap
  368.         lea        _MenuWindow(A4),A0
  369.         call        RemoveBitMap
  370.         bra        Abort2
  371.  
  372. ;   Lock the screen again.
  373. OKToLock:    move.l        A2,A0
  374.         move.l        _LayersBase(A4),A6
  375.         libcall     LockLayers
  376.  
  377. ;   Put everything back on the screen.
  378.         lea        _MenuWindow(A4),A0
  379.         call        SwapBits
  380.         lea        _ItemWindow(A4),A0
  381.         call        SwapBits
  382.         lea        _SubWindow(A4),A0
  383.         call        SwapBits
  384.  
  385. ;   Waiting = FALSE
  386.         moveq.l     #FALSE,D2
  387.         bra        NewTimer
  388.  
  389. ;   Waiting = TRUE
  390. NoLockup:    moveq.l     #TRUE,D2
  391.  
  392. ;   Start a new timer.
  393. NewTimer:    moveq.l     #INPUT_DEVICE_WAIT,D0
  394.         call        QueTimer
  395.  
  396. NextSig:    bra        WaitNextSig
  397.  
  398. ;   All selections done.
  399. ;   Close all windows.
  400. NoMoreSel:    call        CloseSubWindow
  401.         call        CloseItemWindow
  402.         call        CloseMenuWindow
  403.  
  404. ;   Remember the last selection for another time.
  405.         move.w        _CurrentMenuNr(A4),_LastMenus+llm_Num(A4)
  406.  
  407. ;   Clear the MENUSTATE flag
  408. NoMenus:    move.l        _ActiveWindow(A4),A0
  409.         bclr        #WFLG_MENUSTATE_B2,wd_Flags+2(A0)
  410.  
  411. ;   Unlock the screen.
  412.         move.l        A2,A0
  413.         move.l        _LayersBase(A4),A6
  414.         libcall     UnlockLayers
  415.  
  416. ;   Tell the window the good news (MENUPICK).
  417.         move.w        _FirstSelected(A4),D0
  418.         call        TellWindow
  419.  
  420. ;    Release the semaphore
  421. Abort2:     lea        PopUpSemaphore(PC),A0
  422.         move.l        _ExecBase(A4),A6
  423.         libcall     ReleaseSemaphore
  424.  
  425.         move.w        (SP)+,D0
  426.         movem.l     (SP)+,D2-D5/A2/A3/A6
  427.         rts
  428.  
  429. ;*****************************************
  430. ;* struct MenuItem *CheckSelected()      *
  431. ;*                     *
  432. ;* Input:                 *
  433. ;*   none                 *
  434. ;* Output:                 *
  435. ;*   return - Selected item or NULL     *
  436. ;*****************************************
  437. @CheckSelected:
  438.         movem.l     D2/A2/A6,-(SP)
  439.  
  440. ;   Fix Checkmarks etc.
  441.         call        FinalSelect
  442.  
  443. ;   Nothing selected ?
  444.         cmp.w        #MENUNULL,D0
  445.         beq        NoSelection  ; Yes
  446.         move.w        D0,D2     ; D2 = Selected
  447.  
  448. ;   Get the address to the selected item
  449.         move.l        _Menus(A4),A0
  450.         move.l        _IntuitionBase(A4),A6
  451.         libcall     ItemAddress
  452.         move.l        D0,A2     ; A2 = SelectedAddr
  453.  
  454. ;   is thist the first selection ?
  455.         move.l        _LastSelected(A4),D0
  456.         beq        FirstSel     ; Yes
  457.  
  458. ;   Same selection as last time ?
  459.         cmp.l        D0,A2
  460.         beq        NoSelection  ; Yes
  461.  
  462. ;   run down the list of selection to se if this item have been selected before
  463.         moveq.l     #0,D0
  464.         move.w        _FirstSelected(A4),D0
  465.         move.l        _Menus(A4),A0
  466.         libcall     ItemAddress
  467.  
  468.         move.l        D0,A0
  469.  
  470. ;   Special case if it was the first selection
  471.         cmp.w        _FirstSelected(A4),D2
  472.         bne        1$
  473.  
  474. ;   remove the first selection
  475.         move.w        mi_NextSelect(A0),_FirstSelected(A4)
  476.         bra        NextSelFixed
  477.  
  478. ;   follow the NextSelect chain
  479. 1$        moveq.l     #0,D0
  480.         move.w        mi_NextSelect(A0),D0
  481.         cmp.w        #MENUNULL,D0      ; No more selections
  482.         beq        NextSelFixed
  483.  
  484. ;   have we found the item ?
  485.         cmp.w        D2,D0
  486.         bne        2$              ; No
  487.  
  488. ;   remove it from the chain
  489.         move.w        mi_NextSelect(A2),mi_NextSelect(A0)
  490.         bra        NextSelFixed
  491.  
  492. ;   Get next item in chain
  493. 2$        move.l        _Menus(A4),A0
  494.         libcall     ItemAddress
  495.         move.l        D0,A0
  496.         bra        1$
  497.  
  498. ;   Add the item to the chain
  499. NextSelFixed:    move.l        _LastSelected(A4),A0
  500.         move.w        D2,mi_NextSelect(A0)
  501.         bra        EndChain
  502.  
  503. FirstSel:    move.w        D2,_FirstSelected(A4)
  504.  
  505. ;    end the NextSelect chain
  506. EndChain:    move.w        #MENUNULL,mi_NextSelect(A2)
  507.         move.l        A2,_LastSelected(A4)
  508.         move.l        A2,D0
  509.         bra        CheckDone
  510.  
  511. NoSelection:    moveq.l     #NULL,D0
  512.  
  513. CheckDone:    movem.l     (SP)+,D2/A2/A6
  514.         rts
  515.  
  516. ;**********************************************
  517. ;* VOID ClearToggle()                         *
  518. ;*   run down the drag-select list and remove *
  519. ;*   the MENUTOGGLED bit.              *
  520. ;* Input                      *
  521. ;*   none                      *
  522. ;* Output                      *
  523. ;*   none                      *
  524. ;**********************************************
  525. ;   Any items drag selected ?
  526. @ClearToggle:    move.l        A6,-(SP)
  527.         move.l        _FirstDrag(A4),A0
  528.         move.l        A0,D0
  529.         beq        2$          ; No
  530.  
  531.         move.l        _IntuitionBase(A4),A6
  532.  
  533. ;   Clear MENUTOGGLED bit
  534. 1$        bclr        #MENUTOGGLED_B0,mi_Flags(A0)
  535.  
  536. ;   Find the next item in list
  537.         moveq.l     #0,D0
  538.         move.w        mi_NextSelect(A0),D0
  539.         cmp.w        #MENUNULL,D0
  540.         beq        2$         ; No more items
  541.         move.l        _Menus(A4),A0
  542.         libcall     ItemAddress
  543.         move.l        D0,A0
  544.         bra        1$
  545.  
  546. 2$        move.l      (SP)+,A6
  547.         rts
  548.  
  549. ;************************************************
  550. ;* FindItemNr(Item,ItemList) - Find nr of item. *
  551. ;*                        *
  552. ;* Input:                    *
  553. ;*   Item - Item to look for.            *
  554. ;*   ItemList - all items on same level.    *
  555. ;* Output:                    *
  556. ;*   return - Nr of Item or NOITEM        *
  557. ;************************************************
  558. ;    Init a counter
  559. @FindItemNr:    moveq.l     #0,D0
  560.         bra        2$
  561.  
  562. ;   Is this the item ?
  563. 1$        cmp.l        A0,A1
  564.         beq        3$         ; Yes
  565.  
  566. ;   Increment counter
  567.         addq.w        #1,D0
  568.  
  569. ;   Get next item
  570.         move.l        mi_NextItem(A1),A1
  571. 2$        move.l        A1,D1
  572.         bne        1$
  573.  
  574.         moveq.l     #NOITEM,D0
  575. 3$        rts
  576.  
  577. ;*************************************************
  578. ;* FindWindow() - Check if window is still open. *
  579. ;*                         *
  580. ;* Input:                     *
  581. ;*   none                     *
  582. ;* Output:                     *
  583. ;*   return  - TRUE if window is open.         *
  584. ;*************************************************
  585. @FindWindow:    move.l        D2,-(SP)
  586.         move.l        A6,-(SP)
  587.  
  588. ;   Must lock IntuitionBase while we do this
  589.         moveq.l     #0,D0
  590.         move.l        _IntuitionBase(A4),A6
  591.         libcall     LockIBase
  592.  
  593. ;   Get the first open screen
  594.         move.l        ib_FirstScreen(A6),A0
  595.  
  596. ;   run down the list of screens to find our one
  597. 1$        move.l        A0,D1
  598.         beq        5$        ; No more screens
  599.  
  600.         cmp.l        _Screen(A4),A0
  601.         bne        4$        ; Wrong screen, try next
  602.  
  603. ;   Get the first window on the screen
  604.         move.l        sc_FirstWindow(A0),A1
  605.  
  606. ;   find our window
  607. 2$        move.l        A1,D1
  608.         beq        5$           ; No more windows
  609.  
  610.         cmp.l        _ActiveWindow(A4),A1
  611.         bne        3$           ; wrong window, try next
  612.  
  613.         moveq.l     #TRUE,D2   ; Success
  614.         bra        6$
  615.  
  616. 3$        move.l        wd_NextWindow(A1),A1
  617.         bra        2$
  618.  
  619. 4$        move.l        sc_NextScreen(A0),A0
  620.         bra        1$
  621.  
  622. 5$        moveq.l     #FALSE,D2  ; Unsuccessful
  623.  
  624. ;   Unlock IntuitionBase
  625. 6$        move.l        D0,A0
  626.         libcall     UnlockIBase
  627.  
  628.         move.l        D2,D0
  629.  
  630.         move.l        (SP)+,A6
  631.         move.l        (SP)+,D2
  632.         rts
  633.  
  634. ;***************************************************
  635. ;* MouseInWindow(Window) - Is mouse inside window. *
  636. ;*                           *
  637. ;* Input:                       *
  638. ;*   Window    - Window to check.           *
  639. ;* Output:                       *
  640. ;*   return    - TRUE if mouse inside.           *
  641. ;***************************************************
  642. @MouseInWindow: moveq.l     #FALSE,D0
  643.  
  644. ;   MouseX > Window->LeftEdge ?
  645.         move.w        _MouseX(A4),D1
  646.         cmp.w        wwd_LeftEdge(A0),D1
  647.         ble        1$
  648.  
  649. ;   MouseX < Window->RightEdge ?
  650.         cmp.w        wwd_RightEdge(A0),D1
  651.         bge.b        1$
  652.  
  653. ;   MouseY > Window->TopEdge ?
  654.         move.w        _MouseY(A4),D1
  655.         cmp.w        wwd_TopEdge(A0),D1
  656.         ble        1$
  657.  
  658. ;   MouseY < Window->Bottom ?
  659.         cmp.w        wwd_Bottom(A0),D1
  660.         bge        1$
  661.  
  662.         moveq.l     #TRUE,D0
  663. 1$        rts
  664.  
  665. ;****************************************************************
  666. ;* FindMouseItem(Window) - Check if mouse inside an item.       *
  667. ;*                                *
  668. ;* Input:                            *
  669. ;*   ItemWindow - Window with items                *
  670. ;* Output:                            *
  671. ;*   return - Pointer to item under the mousepointer (or NULL). *
  672. ;****************************************************************
  673. @FindMouseItem: move.w        D2,-(SP)
  674.  
  675. ;   MouseWinX = MouseX + Window->LeftValue
  676.         move.w        _MouseX(A4),D1
  677.         add.w        wwd_LeftValue(A0),D1
  678.  
  679. ;   MouseWinY = MouseY + Window->TopValue
  680.         move.w        _MouseY(A4),D2
  681.         add.w        wwd_TopValue(A0),D2
  682.  
  683. ;   Get first item in this window
  684.         move.l        wwd_Items(A0),A0
  685.  
  686. ;   MouseWinY >= Item->TopEdge ?
  687. 1$        move.w        mi_TopEdge(A0),D0
  688.         cmp.w        D0,D2
  689.         blt        2$      ; No
  690.  
  691. ;   MouseWinY <= Item->TopEdge + Item->Height ?
  692.         add.w        mi_Height(A0),D0
  693.         cmp.w        D0,D2
  694.         bgt        2$      ; No
  695.  
  696. ;   MouseWinX >= Item->LeftEdge ?
  697.         move.w        mi_LeftEdge(A0),D0
  698.         cmp.w        D0,D1
  699.         blt        2$      ; No
  700.  
  701. ;   MouseWinX <= Item->LeftEdge + Item->Width ?
  702.         add.w        mi_Width(A0),D0
  703.         cmp.w        D0,D1
  704.         bgt        2$      ;
  705.  
  706. ;   Item found, return it
  707.         move.l        A0,D0
  708.         bra        3$
  709.  
  710. ;   Try next item.
  711. 2$        move.l        mi_NextItem(A0),A0
  712.         move.l        A0,D0
  713.         bne        1$
  714.  
  715. 3$        move.w        (SP)+,D2
  716.         rts
  717.  
  718. ;******************************************
  719. ;* OpenMenuWindow(StartPos)               *
  720. ;*                      *
  721. ;* Input:                  *
  722. ;*   StartPos  - Position from menutop.   *
  723. ;* Output:                  *
  724. ;*   return    - TRUE if window opened.   *
  725. ;******************************************
  726. @OpenMenuWindow:
  727.         movem.l     D5-D7/A3/A5,-(SP)
  728.         move.w        D0,D7
  729.  
  730. ;   Sort menus after their LeftEdge
  731.         call        SortMenus
  732.  
  733.         move.l        _GfxBase(A4),A6
  734.  
  735. ;   Special case if just one menu
  736.         move.l        _Menus(A4),A3
  737.         tst.l        mu_NextMenu(A3)
  738.         bne        2$           ; More than one
  739.  
  740. ;   Single menu name option set ?
  741.         btst        #SHOWSINGLEMENU_B0,_CxHandlerData+ssd_Options(A4)
  742.         bne        2$           ; Yes
  743.  
  744. ;   if the menu is disabled, disable all items
  745.         lea        _ItemWindow(A4),A0
  746.         moveq.l     #MENUENABLED,D0
  747.         and.w        mu_Flags(A3),D0
  748.         move.w        D0,wwd_ItemsEnabled(A0)
  749.  
  750. ;   Set windows items
  751.         move.l        mu_FirstItem(A3),wwd_Items(A0)
  752.  
  753. ;   FindItemWinSize(ItemWindow, ITEMWINDOW)
  754.         moveq.l     #ITEMWINDOW,D0
  755.         call        FindItemWinSize
  756.  
  757.         tst.l        D0
  758.         beq        2$             ; No items
  759.  
  760. ;   MenuWidth = Size.Right - Size.left
  761.         move.w        _Size+wws_Right(A4),D6
  762.         sub.w        _Size+wws_Left(A4),D6
  763.  
  764. ;   Length = TextLength(&Rp,MenuPtr->MenuName,Mystrlen(MenuPtr->MenuName))
  765.         move.l        mu_MenuName(A3),A0
  766.         call        Mystrlen
  767.         lea        _Rp(A4),A1
  768.         move.l        mu_MenuName(A3),A0
  769.         libcall     TextLength
  770.  
  771. ;   Will menu fit inside menuwindow
  772.         cmp.w        D0,D6
  773.         bge        1$           ; Yes
  774.  
  775. ;   Increse window size [Size.Right += Length - MenuWidth]
  776.         move.w        _Size+wws_Right(A4),D1
  777.         add.w        D0,D1
  778.         sub.w        D6,D1
  779.         move.w        D1,_Size+wws_Right(A4)
  780.  
  781. ;   MenuWidth = Length
  782.         move.w        D0,D6
  783.  
  784. ;   Add border
  785. 1$        addq.w        #2*VBORDERSIZE,D6
  786.  
  787. ;   MenuHeight = Size.bottom - Size.Top + 2 * HBORDERSIZE + MenuTextHeight
  788.         move.w        _Size+wws_Bottom(A4),D5
  789.         sub.w        _Size+wws_Top(A4),D5
  790.         addq.w        #2*HBORDERSIZE,D5
  791.         add.w        _MenuTextHeight(A4),D5
  792.  
  793. ;   MenuTop = 0
  794.         moveq.l     #0,D7
  795.  
  796. ;   Window = ItemWindow
  797.         lea        _ItemWindow(A4),A3
  798.  
  799. ;   Window->CommKeySize = Size.CommKey
  800.         move.w        _Size+wws_CommKey(A4),wwd_CommKeySize(A3)
  801.  
  802.         bra        PosLeft
  803.  
  804. ;   MenuWidth = 0
  805. 2$        moveq.l     #0,D6
  806.  
  807. ;   MenuHeight = HBORDERSIZE + 1
  808.         moveq.l     #HBORDERSIZE+1,D5
  809.  
  810. ;****************************************
  811. ;* Find width & height of window needed *
  812. ;****************************************
  813. ;***********************************
  814. ;* D5 = MenuHeight    A3 = Menus   *
  815. ;* D6 = MenuWidth     A6 = GfxBase *
  816. ;* D7 = MenuTop            *
  817. ;***********************************
  818. ;   Length = TextLength(&Rp,MenuPtr->MenuName,Mystrlen(MenuPtr->MenuName))
  819. 3$        move.l        mu_MenuName(A3),A0
  820.         call        Mystrlen
  821.         lea        _Rp(A4),A1
  822.         move.l        mu_MenuName(A3),A0
  823.         libcall     TextLength
  824.  
  825. ;   MenuPtr->Width > Length ?
  826.         move.w        mu_Width(A3),D1
  827.         cmp.w        D0,D1
  828.         bls        4$          ; No
  829.  
  830. ;   Length = MenuPtr->Width
  831.         move.l        D1,D0
  832.  
  833. ;   Length > MenuWidth ?
  834. 4$        cmp.w        D6,D0
  835.         bls        5$          ; No
  836.  
  837. ;   MenuWidth = Length
  838.         move.w        D0,D6
  839.  
  840. ;   MenuHeight += MenuTextHeight
  841. 5$        add.w        _MenuTextHeight(A4),D5
  842.  
  843. ;   Check next menu.
  844.         move.l        mu_NextMenu(A3),A3
  845.         move.l        A3,D0
  846.         bne        3$
  847.  
  848. ;   MenuWidth += (2 * VBORDERSIZE + 1)
  849.         addq.w        #2*VBORDERSIZE,D6
  850.         addq.w        #1,D6
  851.  
  852. ;   Window = MenuWindow
  853.         lea        _MenuWindow(A4),A3
  854.  
  855. ;************************************
  856. ;* Position window on screen (Left) *
  857. ;************************************
  858. ;***********************************
  859. ;*              A3 = Window  *
  860. ;* D5 = MenuHeight    A6 = GfxBase *
  861. ;* D6 = MenuWidth           *
  862. ;* D7 = MenuTop            *
  863. ;***********************************
  864. ;   MenuLeft = Screen->MouseX - MenuWidth / 2
  865. PosLeft:    move.w        D6,D0
  866.         lsr.w        #1,D0
  867.         move.l        _Screen(A4),A0
  868.         move.w        sc_MouseX(A0),D1
  869.         sub.w        D0,D1
  870.  
  871. ;   MenuLeft < 0 ?
  872.         bge        1$          * No
  873.  
  874. ;   MenuLeft = 0
  875.         moveq.l     #0,D1
  876.  
  877. ;   MenuLeft > Screen->Width - MenuWidth ?
  878. 1$        move.w        sc_Width(A0),D0
  879.         sub.w        D6,D0
  880.         cmp.w        D0,D1
  881.         ble        PosTop      * No
  882.  
  883. ;   MenuLeft = Screen->Width - MenuWidth
  884.         move.w        D0,D1
  885.  
  886. ;***********************************
  887. ;* Position window on screen (Top) *
  888. ;***********************************
  889. ;***********************************
  890. ;* D1 = MenuLeft      A3 = Window  *
  891. ;* D5 = MenuHeight    A0 = Screen  *
  892. ;* D6 = MenuWidth     A6 = GfxBase *
  893. ;* D7 = MenuTop            *
  894. ;***********************************
  895. ;   MenuTop > MenuHeight ? (Menus has changed)
  896. PosTop:     cmp.w        D5,D7
  897.         ble        1$          * No
  898.  
  899. ;   MenuTop = 0
  900.         moveq.l     #0,D7
  901.  
  902. ;   MenuTop  = Screen->MouseY - MenuTextHeight/2 - MenuTop
  903. 1$        move.w        _MenuTextHeight(A4),D0
  904.         lsr.w        #1,D0
  905.         add.w        D0,D7
  906.         sub.w        sc_MouseY(A0),D7
  907.         neg.w        D7
  908.  
  909. ;   MenuTop < 0 ?
  910.         bpl.b        2$          * No
  911.  
  912. ;   MenuTop = 0
  913.         moveq.l     #0,D7
  914.  
  915. ;   MenuTop > Screen->Height - MenuHeight ?
  916. 2$        move.w        sc_Height(A0),D0
  917.         sub.w        D5,D0
  918.         cmp.w        D0,D7
  919.         ble        3$          * No
  920.  
  921. ;   MenuTop = Screen->Height - MenuHeight
  922.         move.l        D0,D7
  923.  
  924. ;   Window->TopEdge = MenuTop
  925. 3$        move.w        D7,wwd_TopEdge(A3)
  926.  
  927. ;   Window->Height = MenuHeight
  928.         move.w        D5,wwd_Height(A3)
  929.  
  930. ;   Window->LeftEdge = MenuLeft
  931.         move.w        D1,wwd_LeftEdge(A3)
  932.  
  933. ;   Window->Width = MenuWidth;
  934.         move.w        D6,wwd_Width(A3)
  935.  
  936. ;*******************************
  937. ;* Open window with right size *
  938. ;*******************************
  939. ;   BuildBitMap(Window)
  940. Open:        move.l        A3,A0
  941.         call        BuildBitMap
  942.  
  943. ;   Window opened OK ?
  944.         tst.w        D0
  945.         beq        OpenMenuDone  ; No
  946.  
  947. ;   Window == ItemWindow ?   [ only if single menu ]
  948.         lea        _ItemWindow(A4),A0
  949.         cmp.l        A0,A3
  950.         bne        1$               ; No
  951.  
  952. ;   ItemWindow.leftValue = Size.left - WindowLeft - VBORDERSIZE
  953.         move.w        _Size+wws_Left(A4),D0
  954.         sub.w        wwd_LeftEdge(A3),D0
  955.         subq.w        #VBORDERSIZE,D0
  956.         move.w        D0,wwd_LeftValue(A3)
  957.  
  958. ;   ItemWindow.TopValue = Size.Top - WindowTop - HBORDERSIZE - MenuTextHeight
  959.         move.w        _Size+wws_Top(A4),D0
  960.         sub.w        wwd_TopEdge(A3),D0
  961.         subq.w        #HBORDERSIZE,D0
  962.         sub.w        _MenuTextHeight(A4),D0
  963.         move.w        D0,wwd_TopValue(A3)
  964.  
  965. ;   DrawAllItems(&ItemWindow)
  966.         move.l        A3,A0
  967.         call        DrawAllItems
  968.  
  969. ;   CurrentMenuNr = 1
  970.         moveq.l     #1,D0
  971.         move.w        D0,_CurrentMenuNr(A4)
  972.         bra        2$
  973.  
  974. ;   Clear window
  975. 1$        move.l        A3,A0
  976.         call        ClearWindow
  977.  
  978. ;   DrawAllMenus(Window)
  979. 2$        move.l        A3,A0
  980.         call        DrawAllMenus
  981.  
  982.         moveq.l     #TRUE,D0
  983.  
  984. OpenMenuDone:    movem.l     (SP)+,D5-D7/A3/A6
  985.         rts
  986.  
  987. ;**************************************
  988. ;* BOOL SortMenus(VOID)  -            *
  989. ;*    sort menus after their LeftEdge *
  990. ;**************************************
  991. @SortMenus:    movem.l     A2/A3/A5,-(SP)
  992.         move.l        _Menus(A4),A0
  993.         lea        _MenuSorted(A4),A1
  994.         move.l        A1,A2
  995.  
  996. ;   First menu
  997.         move.l        A0,(A2)+
  998.         bra        4$
  999.  
  1000. 1$        move.w        mu_LeftEdge(A0),D0
  1001.         move.l        A2,A3
  1002.  
  1003. 2$        move.l        -4(A3),A5
  1004.         cmp.w        mu_LeftEdge(A5),D0
  1005.         bge        3$
  1006.  
  1007.         move.l        -4(A3),(A3)
  1008.         subq.l        #4,A3
  1009.         cmp.l        A3,A1
  1010.         bne        2$
  1011.  
  1012. 3$        move.l        A0,(A3)
  1013.         addq.l        #4,A2
  1014.  
  1015. 4$        move.l        mu_NextMenu(A0),A0
  1016.         move.l        A0,D0
  1017.         bne        1$
  1018.  
  1019.         movem.l     (SP)+,A2/A3/A5
  1020.         rts
  1021.  
  1022. ;*****************************************************************
  1023. ;* OpenItemWindow(ItemWindow,WindowType,LeftPos,RightPos,TopPos) *
  1024. ;*            A0           D0     D1      D2      D3     *
  1025. ;* Input:                             *
  1026. ;*   ItemWindow   - Window to open.                 *
  1027. ;*   WindowType.w - ITEMWINDOW or SUBWINDOW             *
  1028. ;*   LeftPos,RightPos,TopPos  - Position(s) for new window.      *
  1029. ;* Output:                             *
  1030. ;*   return      - TRUE if OK                     *
  1031. ;*****************************************************************
  1032. @OpenItemWindow:
  1033.         movem.l     D4/D5/A2,-(SP)
  1034.         move.l        A0,A2
  1035.         move.l        D0,D4
  1036.         move.l        D1,D5
  1037.  
  1038. ;   FindItemWinSize(Window,WindowType)
  1039.         call        FindItemWinSize
  1040.  
  1041. ;   Empty menu ?
  1042.         tst.l        D0
  1043.         beq        1$          ; Yes
  1044.  
  1045. ;   Set largest CommKeySize  [Window->CommKeySize = Size.CommKey]
  1046.         move.w        _Size+wws_CommKey(A4),wwd_CommKeySize(A2)
  1047.  
  1048. ;   PosItemWinLeft(Window,WindowType,LeftPos,RightPos)
  1049.         move.l        A2,A0
  1050.         move.w        D4,D0
  1051.         move.l        D5,D1
  1052.         call        PosItemWinLeft
  1053.  
  1054. ;   PosItemWinTop(Window, TopPos, WindowType)
  1055.         move.l        A2,A0
  1056.         move.w        D3,D0
  1057.         move.w        D4,D1
  1058.         call        PosItemWinTop
  1059.  
  1060. ;   BuildBitMap(Window)
  1061.         move.l        A2,A0
  1062.         call        BuildBitMap
  1063.  
  1064.         tst.w        D0
  1065.         beq        1$
  1066.  
  1067. ;   DrawAllItems(Window)
  1068.         move.l        A2,A0
  1069.         call        DrawAllItems
  1070.  
  1071.         moveq.l     #TRUE,D0
  1072.  
  1073. 1$        movem.l     (SP)+,D4/D5/A2
  1074.         rts
  1075.  
  1076. ;******************************************************
  1077. ;* PosItemWinLeft(Window,WindowType,LeftPos,RightPos) *
  1078. ;* - Position window on screen (left)                 *
  1079. ;*                              *
  1080. ;* Input:                          *
  1081. ;*   Window      - Window to position.           *
  1082. ;*   ParentWindow - Window to position next to.       *
  1083. ;*   WindowType.w - ITEMWINDOW or SUBWINDOW.          *
  1084. ;*                              *
  1085. ;* Possible positions:                      *
  1086. ;*   1. At real position (a'la intuition).            *
  1087. ;*   2. At right side of parent.              *
  1088. ;*   3. At left side of parent.               *
  1089. ;*   4. On the side that covers parent least.          *
  1090. ;******************************************************
  1091. @PosItemWinLeft:
  1092.         movem.l     D3-D7/A2,-(SP)
  1093.  
  1094. ;   LeftValue = Size.left - VBORDERSIZE
  1095.         move.w        _Size+wws_Left(A4),D6
  1096.         subq.w        #VBORDERSIZE,D6
  1097.  
  1098. ;   WindowWidth = Size.Right - LeftValue + VBORDERSIZE
  1099.         move.w        _Size+wws_Right(A4),D5
  1100.         sub.w        D6,D5
  1101.         addq.w        #VBORDERSIZE,D5
  1102.  
  1103. ;   LeftPos2 = ParentWindow->LeftEdge - WindowWidth + OVERLAP
  1104.         move.w        D1,D4
  1105.         sub.w        D5,D4
  1106.         addq.w        #OVERLAP,D4
  1107.  
  1108. ;   MaxLeft = Screen->Width - WindowWidth
  1109.         move.l        _Screen(A4),A2
  1110.         move.w        sc_Width(A2),D3
  1111.         sub.w        D5,D3
  1112.  
  1113. ;**********************************************
  1114. ;* D0 = WindowType       A0 = Window          *
  1115. ;* D1 = LeftPos        A1 = ParentWindow  *
  1116. ;* D2 = RightPos       A2 = Screen          *
  1117. ;* D3 = MaxLeft                   *
  1118. ;* D4 = LeftPos2                  *
  1119. ;* D5 = WindowWidth                  *
  1120. ;* D6 = LeftValue                  *
  1121. ;* D7 = WindowLeft                  *
  1122. ;**********************************************
  1123. ;   WindowType == ITEMWINDOW ?
  1124.         tst.w        D0
  1125.         beq        1$      ; Yes
  1126.  
  1127. ;   WindowLeft = ParentWindow->LeftEdge + LeftValue
  1128.         move.w        D1,D7
  1129.         add.w        D6,D7
  1130.  
  1131. ;   WindowLeft > MaxLeft ?
  1132.         cmp.w        D7,D3
  1133.         blt        1$      ; Yes
  1134.  
  1135. ;   WindowLeft < 0 ?
  1136.         tst.w        D7
  1137.         bpl.b        2$      ; No
  1138.  
  1139. ;   WindowLeft = ParentWindow->RightEdge - OVERLAP
  1140. 1$        move.w        D2,D7
  1141.         subq.w        #OVERLAP,D7
  1142.  
  1143. ;   WindowLeft > MaxLeft ?
  1144. 2$        cmp.w        D7,D3
  1145.         bge        4$      ; No
  1146.  
  1147. ;   LeftPos2 > MaxLeft - WindowLeft ?
  1148.         move.w        D3,D0
  1149.         sub.w        D7,D0
  1150.         cmp.w        D4,D0
  1151.         bge        3$      ; No
  1152.  
  1153. ;   WindowLeft = (LeftPos2 > 0) ? LeftPos2 : 0
  1154.         move.w        D4,D7
  1155.         bgt        4$
  1156.  
  1157.         moveq.l     #0,D3    ; MaxLeft not needed any more
  1158.  
  1159. ;   WindowLeft = MaxLeft
  1160. 3$        move.w        D3,D7
  1161.  
  1162. ;   WindowWidth < ParentWindow->LeftEdge + OVERLAP - WindowLeft ?
  1163. 4$        move.w        D1,D0
  1164.         addq.w        #OVERLAP,D0
  1165.         sub.w        D7,D0
  1166.         cmp.w        D5,D0
  1167.         ble        5$          ; No
  1168.  
  1169. ;   WindowWidth = ParentWindow->LeftEdge + OVERLAP - WindowLeft
  1170.         move.w        D0,D5
  1171.  
  1172. ;   Window->LeftEdge = WindowLeft
  1173. 5$        move.w        D7,wwd_LeftEdge(A0)
  1174.  
  1175. ;   Window->LeftValue = LeftValue - WindowLeft
  1176.         sub.w        D7,D6
  1177.         move.w        D6,wwd_LeftValue(A0)
  1178.  
  1179. ;   Window->Width = WindowWidth
  1180.         move.w        D5,wwd_Width(A0)
  1181.  
  1182.         movem.l     (SP)+,D3-D7/A2
  1183.         rts
  1184.  
  1185. ;*****************************************************
  1186. ;* PosItemWinTop(Window,TopPos, WindowType)          *
  1187. ;* - Position Window on screen (Top).                *
  1188. ;*                             *
  1189. ;* Input:                         *
  1190. ;*   Window      - Window to position. (A0)         *
  1191. ;*   TopPos.w      -            (D0)         *
  1192. ;*   WindowType.w - ITEMWINDOW or SUBWINDOW (D1)     *
  1193. ;*****************************************************
  1194. @PosItemWinTop:
  1195.         movem.l     D4-D7,-(SP)
  1196.  
  1197. ;   TopValue = Size.Top - HBORDERSIZE
  1198.         move.w        _Size+wws_Top(A4),D6
  1199.         subq.w        #HBORDERSIZE,D6
  1200.  
  1201. ;   WindowHeight = Size.bottom - TopValue + HBORDERSIZE
  1202.         move.w        _Size+wws_Bottom(A4),D4
  1203.         sub.w        D6,D4
  1204.         addq.w        #HBORDERSIZE,D4
  1205.         move.l        _Screen(A4),A1
  1206.  
  1207. ;   WindowTop = TopPos
  1208.         move.w        D0,D5
  1209.  
  1210. ;   WindowType == ITEMWINDOW ?
  1211.         tst.w        D1
  1212.         bne        1$          ; No
  1213.  
  1214. ;   Center Items ?
  1215.         btst        #ITEMSCENTERED_B0,_CxHandlerData+ssd_Options(A4)
  1216.         beq        1$          * No
  1217.  
  1218. ;   WindowTop += (MenuTextHeight - WindowHeight) / 2
  1219.         move.w        _MenuTextHeight(A4),D1
  1220.         sub.w        D4,D1
  1221.         asr.w        #1,D1
  1222.         add.w        D1,D5
  1223.         bra        2$
  1224.  
  1225. ;   WindowTop = TopPos + TopValue
  1226. 1$        add.w        D6,D5
  1227.  
  1228. ;***********************************
  1229. ;* D0 = TopPos          A0 = Window  *
  1230. ;* D4 = WindowHeight  A1 = Screen  *
  1231. ;* D5 = WindowTop           *
  1232. ;* D6 = TopValue           *
  1233. ;***********************************
  1234. ;   WindowTop > Screen->Height - WindowHeight ?
  1235. 2$        move.w        sc_Height(A1),D0
  1236.         sub.w        D4,D0
  1237.         cmp.w        D5,D0
  1238.         bge        3$          ; No
  1239.  
  1240. ;   WindowTop = Screen->Height - WindowHeight
  1241.         move.w        D0,D5
  1242.  
  1243. ;   WindowTop < 0 ?
  1244. 3$        tst.w        D5
  1245.         bpl.b        4$          ; No
  1246.  
  1247. ;   WindowTop = 0
  1248.         moveq.l     #0,D5
  1249.  
  1250. ;   Window->TopEdge = WindowTop
  1251. 4$        move.w        D5,wwd_TopEdge(A0)
  1252.  
  1253. ;   Window->TopValue = TopValue - WindowTop
  1254.         sub.w        D5,D6
  1255.         move.w        D6,wwd_TopValue(A0)
  1256.  
  1257. ;   Window->Height = WindowHeight
  1258.         move.w        D4,wwd_Height(A0)
  1259.  
  1260.         movem.l     (SP)+,D4-D7
  1261.         rts
  1262.  
  1263. ;********************************************************
  1264. ;*  TellWindow(MenuNum) - Send Fake Menu Event.         *
  1265. ;*          D0                    *
  1266. ;* Input:                        *
  1267. ;*   MenuNum -     Menu number to send.            *
  1268. ;* Output:                        *
  1269. ;*   none                        *
  1270. ;********************************************************
  1271. @TellWindow:    move.l        A6,-(SP)
  1272.         lea        -ie_SIZEOF(SP),SP
  1273.  
  1274. ;   MyEvent.ie_Class = IECLASS_MENULIST
  1275.         move.b        #IECLASS_MENULIST,ie_Class(SP)
  1276.  
  1277. ;   MyEvent.ie_Code = MenuNumber
  1278.         move.w        D0,ie_Code(SP)
  1279.  
  1280. ;   MyEvent.ie_Qualifier = InputSignals.EndQualifier
  1281.         move.w        _CxHandlerData+ssd_EndQualifier(A4),ie_Qualifier(SP)
  1282.  
  1283. ;   MyEvent.ie_NextEvent = NULL
  1284.         clr.l        (SP)
  1285.  
  1286. ;   MyEvent.ie_EventAddress = ActiveWindow
  1287.         move.l        _ActiveWindow(A4),ie_EventAddress(SP)
  1288.  
  1289. ;   Intuition will set the mouse position in the MENUPICK message
  1290.  
  1291. ;   Get current time.
  1292.         lea        ie_TimeStamp+TV_SECS(SP),A0
  1293.         lea        ie_TimeStamp+TV_MICRO(SP),A1
  1294.         move.l        _IntuitionBase(A4),A6
  1295.         libcall     CurrentTime
  1296.  
  1297. ;   Send the menu event
  1298.         move.l        _CxBase(A4),A6
  1299.         move.l        SP,A0
  1300.         libcall     AddIEvents
  1301.  
  1302. 1$        lea        ie_SIZEOF(SP),SP
  1303.         move.l        (SP)+,A6
  1304.         rts
  1305.  
  1306. ;****************************************
  1307. ;* DrawAllItems(Window)                 *
  1308. ;*                    *
  1309. ;* Input:                *
  1310. ;*   Window  - Window to draw into.    *
  1311. ;*                    *
  1312. ;* Output:                *
  1313. ;*   none                *
  1314. ;****************************************
  1315. @DrawAllItems:    move.l        A2,-(SP)
  1316.         move.l        A3,-(SP)
  1317.  
  1318.         move.l        A0,A3
  1319.  
  1320. ;   ClearWindow(Window)
  1321.         call        ClearWindow
  1322.  
  1323. ;   Item = Window->Items
  1324.         move.l        wwd_Items(A3),A2
  1325.  
  1326. ;   DrawMenuItem(Window, Item, ITEMFILL)
  1327. 1$        moveq.l     #ITEMFILL,D0
  1328.         move.l        A3,A0
  1329.         move.l        A2,A1
  1330.         call        DrawMenuItem
  1331.  
  1332. ;   Item = Item->NextItem
  1333.         move.l        mi_NextItem(A2),A2
  1334.         move.l        A2,D0
  1335.         bne        1$
  1336.  
  1337.         move.l        (SP)+,A3
  1338.         move.l        (SP)+,A2
  1339.         rts
  1340.  
  1341. ;*********************************
  1342. ;* ClearWindow(window)           *
  1343. ;*                 *
  1344. ;* Input:             *
  1345. ;*   Window   - Window to clear. *
  1346. ;* Output:             *
  1347. ;*   none             *
  1348. ;*********************************
  1349. @ClearWindow:    movem.l     D2-D5/A2/A3/A6,-(SP)
  1350.         move.l        A0,A3
  1351.  
  1352.         lea        _Rp(A4),A2
  1353.         move.l        _GfxBase(A4),A6
  1354. ;*********************
  1355. ;* A2 = Rp         *
  1356. ;* A3 = Window         *
  1357. ;* A6 = GfxBase      *
  1358. ;*********************
  1359. ;   SetDrMd(Rp, JAM1)
  1360.         move.l        A2,A1
  1361.         moveq.l     #RP_JAM1,D0
  1362.         libcall     SetDrMd
  1363.  
  1364. ;   SetAPen(Rp,DetailPen)
  1365.         move.l        A2,A1
  1366.         moveq.l     #0,D0
  1367.         move.b        _DetailPen(A4),D0
  1368.         libcall     SetAPen
  1369.  
  1370. ;   Left = Window->LeftEdge
  1371.         moveq.l     #0,D0
  1372.         move.w        wwd_LeftEdge(A3),D0
  1373.  
  1374. ;   Top = Window->TopEdge
  1375.         moveq.l     #0,D1
  1376.         move.w        wwd_TopEdge(A3),D1
  1377.  
  1378. ;   Right = Window->RightEdge
  1379.         moveq.l     #0,D2
  1380.         move.w        wwd_RightEdge(A3),D2
  1381.  
  1382. ;   Bottom = Window->Bottom
  1383.         moveq.l     #0,D3
  1384.         move.w        wwd_Bottom(A3),D3
  1385.  
  1386. ;   DrawRect(Left, Top, Right, Bottom)
  1387.         move.l        A2,A1
  1388.         bsr        DrawRect
  1389.  
  1390. ;   Save Left & Top.
  1391.         move.l        D0,D4
  1392.         move.l        D1,D5
  1393.  
  1394. ;   SetAPen(Rp,BlockPen)
  1395.         move.l        A2,A1
  1396.         moveq.l     #0,D0
  1397.         move.b        _BlockPen(A4),D0
  1398.         libcall     SetAPen
  1399.  
  1400. ;   RectFill(Left, Top, Right, Bottom)
  1401.         move.l        A2,A1
  1402.         move.l        D4,D0
  1403.         move.l        D5,D1
  1404.         libcall     RectFill
  1405.  
  1406.         movem.l     (SP)+,D2-D5/A2/A3/A6
  1407.         rts
  1408.  
  1409. ;*******************************
  1410. ;* VOID CloseSubWindow(VOID)   *
  1411. ;* VOID CloseItemWindow(VOID)  *
  1412. ;* VOID CloseMenuWindow(VOID)  *
  1413. ;*******************************
  1414. @CloseSubWindow:
  1415.         lea        _SubWindow(A4),A0
  1416.         tst.w        wwd_BitMapOk(A0)
  1417.         beq        CloseQuit      ; Not open
  1418.  
  1419.         move.l        wwd_Current(A0),A1
  1420.         move.l        A1,D0
  1421.         beq        1$          ; No item selected
  1422.         bclr        #HIGHITEM_B0,mi_Flags(A1)
  1423.         clr.l        wwd_Current(A0)
  1424.  
  1425. ;   If subitems are shown ItemWindow.Current must be something.
  1426. 1$        move.l        _ItemWindow+wwd_Current(A4),A1
  1427.         bclr        #ISDRAWN_B0,mi_Flags(A1)
  1428.         bra        Close
  1429.  
  1430. @CloseItemWindow:
  1431.         lea        _ItemWindow(A4),A0
  1432.         tst.w        wwd_BitMapOk(A0)
  1433.         beq        CloseQuit      ; Not open
  1434.  
  1435.         move.l        wwd_Current(A0),A1
  1436.         move.l        A1,D0
  1437.         beq        1$          ; No item selected
  1438.         bclr        #HIGHITEM_B0,mi_Flags(A1)
  1439.         clr.l        wwd_Current(A0)
  1440.  
  1441. 1$        move.l        _MenuWindow+wwd_Current(A4),A1
  1442.         move.l        A1,D0
  1443.         beq        Close
  1444.         bclr        #MIDRAWN_B0,mu_Flags(A1)
  1445.         bra        Close
  1446.  
  1447. @CloseMenuWindow:
  1448.         lea        _MenuWindow(A4),A0
  1449.  
  1450. Close:        move.l        A0,-(SP)
  1451.  
  1452. ;   Remove window from screen.
  1453. ;         call         MoveToScreen  ; (Dont care about data in window)
  1454.         call        SwapBits
  1455.  
  1456. ;   Remove all bitplanes.
  1457.         move.l        (SP)+,A0
  1458.         call        RemoveBitMap
  1459.  
  1460. CloseQuit:    rts
  1461.  
  1462.  
  1463. ;****************************************
  1464. ;* BuildBitMap(Window)  - OpenWindow    *
  1465. ;*                    *
  1466. ;* Input:                *
  1467. ;*   Window    - Window to open.    *
  1468. ;* Output:                *
  1469. ;*   return    - TRUE if window opened. *
  1470. ;****************************************
  1471. @BuildBitMap:    movem.l     D2-D5/A2/A3/A6,-(SP)
  1472.         move.l        A0,A3
  1473.  
  1474. ;   WindowWidth = Window->Width
  1475.         moveq.l     #0,D3
  1476.         move.w        wwd_Width(A3),D3
  1477.  
  1478. ;   WindowHeight = Window->Height
  1479.         moveq.l     #0,D2
  1480.         move.w        wwd_Height(A3),D2
  1481.  
  1482.         move.l        _Screen(A4),A0
  1483.  
  1484. ;**************************************
  1485. ;* D2 = WindowHeight      A0 = Screen *
  1486. ;* D3 = WindowWidth      A3 = Window *
  1487. ;**************************************
  1488. ;   Is window to big for screen ?
  1489. ;   WindowWidth > Screen->Width
  1490.         cmp.w        sc_Width(A0),D3
  1491.         bgt        Fail      * Yes
  1492.  
  1493. ;   WindowHeight > Screen->Height
  1494.         cmp.w        sc_Height(A0),D2
  1495.         bgt        Fail      * Yes
  1496.  
  1497. ;   Window->RightEdge = Window->LeftEdge + WindowWidth    - 1
  1498.         move.l        D3,D0
  1499.         add.w        wwd_LeftEdge(A3),D0
  1500.         subq.l        #1,D0
  1501.         move.w        D0,wwd_RightEdge(A3)
  1502.  
  1503. ;   Window->Bottom    = Window->TopEdge  + WindowHeight - 1
  1504.         move.l        D2,D0
  1505.         add.w        wwd_TopEdge(A3),D0
  1506.         subq.l        #1,D0
  1507.         move.w        D0,wwd_Bottom(A3)
  1508.  
  1509. ;   Depth = Screen->BitMap.Depth
  1510.         moveq.l     #0,D5
  1511.         move.b        sc_BitMap+bm_Depth(A0),D5
  1512.  
  1513.         move.l        _GfxBase(A4),A6
  1514.  
  1515. ;***************************************
  1516. ;* D2 = WindowHeight      A0 = Screen  *
  1517. ;* D3 = WindowWidth      A3 = Window  *
  1518. ;* D5 = Depth          A6 = GfxBase *
  1519. ;***************************************
  1520. ;   InitBitMap(&Window->Bm,Depth,WindowWidth,WindowHeight)
  1521.         lea        wwd_Bm(A3),A0
  1522.         move.l        D5,D0
  1523.         move.l        D3,D1
  1524.         libcall     InitBitMap
  1525.  
  1526. ;   Window->BitMapOk = TRUE
  1527.         move.w        #TRUE,wwd_BitMapOk(A3)
  1528.  
  1529. ;   Counter = 0
  1530.         moveq.l     #0,D4
  1531.  
  1532. ;   Plane = &Window->Bm.Planes[0]
  1533.         lea        wwd_Bm+bm_Planes(A3),A2
  1534.  
  1535. ;***************************************
  1536. ;* D2 = WindowHeight      A2 = Planes  *
  1537. ;* D3 = WindowWidth      A3 = Window  *
  1538. ;* D4 = Counter       A6 = GfxBase *
  1539. ;* D5 = Depth                   *
  1540. ;***************************************
  1541. ;   More planes to allocate ?
  1542. BuildNextPl:    cmp.w        D4,D5
  1543.         beq        AllRastersOK
  1544.         addq.w        #1,D4
  1545.  
  1546. ;   Plane++ = AllocRaster(WindowWidth,WindowHeight)
  1547.         move.l        D3,D0
  1548.         move.l        D2,D1
  1549.         libcall     AllocRaster
  1550.         move.l        D0,(A2)+
  1551.  
  1552. ;   Out of ChipRam ?
  1553.         bne        BuildNextPl   ; No
  1554.  
  1555. ;   RemoveBitMap(Window)
  1556.         move.l        A3,A0
  1557.         call        RemoveBitMap
  1558.  
  1559. ;   return FALSE
  1560. Fail:        moveq.l     #FALSE,D0
  1561.         bra        BuildDone
  1562.  
  1563. ;   Make window visible.
  1564. AllRastersOK:    move.l        A3,A0
  1565.         call        MoveFromScreen    ; Don't care whats in offscreen bitmap
  1566.  
  1567. ;   return TRUE
  1568.         moveq.l     #TRUE,D0
  1569.  
  1570. BuildDone:    movem.l     (SP)+,D2-D5/A2/A3/A6
  1571.         rts
  1572.  
  1573. ;***************************************************************
  1574. ;* VOID RemoveBitMap(Window) -                                 *
  1575. ;*         Remove allocated rasters in the BitMap structure. *
  1576. ;*                                   *
  1577. ;* Input:                               *
  1578. ;*   Window   - Window with bitmap.                   *
  1579. ;* Output:                               *
  1580. ;*   none                               *
  1581. ;***************************************************************
  1582. @RemoveBitMap:    movem.l     D4-D7/A2/A6,-(SP)
  1583.  
  1584. ;   Anything to remove ?
  1585.         tst.w        wwd_BitMapOk(A0)
  1586.         beq        RemoveDone
  1587.         clr.w        wwd_BitMapOk(A0)
  1588.  
  1589. ;   Remove all allocated rasters.
  1590.         moveq.l     #0,D7
  1591.         lea        wwd_Bm(A0),A2
  1592.         move.b        bm_Depth(A2),D7
  1593.  
  1594.         moveq.l     #0,D6
  1595.         move.w        wwd_Width(A0),D6
  1596.  
  1597.         moveq.l     #0,D5
  1598.         move.w        wwd_Height(A0),D5
  1599.  
  1600.         addq.l        #bm_Planes,A2
  1601.  
  1602.         move.l        _GfxBase(A4),A6
  1603.  
  1604. ;   Counter = 0
  1605.         moveq.l     #0,D4
  1606. ;*************************************
  1607. ;* D4 = Counter     A2 = Planes  *
  1608. ;* D5 = WindowHeight    A0 = Window  *
  1609. ;* D6 = WindowWidth    A6 = GfxBase *
  1610. ;* D7 = Depth                 *
  1611. ;*************************************
  1612. RemoveNextPl:    cmp.w        D4,D7
  1613.         beq        RemoveDone
  1614.         addq.w        #1,D4
  1615.  
  1616. ;   This raster allocated ?
  1617.         move.l        (A2)+,A0
  1618.         move.l        A0,D0
  1619.         beq        RemoveDone
  1620.  
  1621. ;   FreeRaster(Planes++,Width,Height);
  1622.         move.l        D6,D0
  1623.         move.l        D5,D1
  1624.         libcall     FreeRaster
  1625.         bra        RemoveNextPl
  1626.  
  1627. RemoveDone:    movem.l     (SP)+,D4-D7/A2/A6
  1628.         rts
  1629.  
  1630. ALLPLANES    equ        -1
  1631.  
  1632. ;*********************************************
  1633. ;* Move data from screen to offscreen bitmap *
  1634. ;*********************************************
  1635. @MoveFromScreen:
  1636.         movem.l     D2-D7/A2/A6,-(SP)
  1637.         bsr        LoadSwapData
  1638.         bra        MoveTo1
  1639.  
  1640. ;*********************************************
  1641. ;* Move data from offscreen bitmap to screen *
  1642. ;*********************************************
  1643. @MoveToScreen:    movem.l     D2-D7/A2/A6,-(SP)
  1644.         bsr        LoadSwapData
  1645.         exg.l        A0,A1
  1646.         exg.l        D0,D2
  1647.         exg.l        D1,D3
  1648.  
  1649. MoveTo1:    moveq.l     #-$40,D6        ; A = B    (ABC+ABNC)
  1650.         libcall     BltBitMap
  1651.         movem.l     (SP)+,D2-D7/A2/A6
  1652.         rts
  1653.  
  1654. ;************************************
  1655. ;* Swap screen and offscreen bitmap *
  1656. ;************************************
  1657. @SwapBits:    tst.w        wwd_BitMapOk(A0)
  1658.         beq        1$
  1659.  
  1660.         movem.l     D2-D7/A2/A6,-(SP)
  1661.         bsr        LoadSwapData
  1662.         moveq.l     #ABNC+ANBC,D6   ; A = B ^ C  (ABNC+ANBC)
  1663.         bsr        Swap   ; OffScreen = (OffScreen XOR OnScreen )
  1664.         bsr        Swap   ; OnScreen  = (OnScreen  XOR OffScreen)
  1665.         bsr        Swap   ; OffScreen = (OffScreen XOR OnScreen )
  1666.         movem.l     (SP)+,D2-D7/A2/A6
  1667.  
  1668. 1$        rts
  1669.  
  1670. Swap:        movem.l     D0/D1/A0/A1,-(SP)
  1671.         libcall     BltBitMap
  1672.         movem.l     (SP)+,D0/D1/A0/A1
  1673.  
  1674.         exg.l        A0,A1
  1675.         exg.l        D0,D2
  1676.         exg.l        D1,D3
  1677.  
  1678.         rts
  1679.  
  1680.  
  1681. ;**************************************************
  1682. ;* LoadSwapData(Window) - load data for BltBitMap *
  1683. ;*                          *
  1684. ;* D0,D1 = SrcX,SrcY    (on screen)               *
  1685. ;* D2,D3 = DextX,DestY    (off screen)              *
  1686. ;* D4,D5 = SizeX,SizeY    (both)                    *
  1687. ;* D7     = ALLPLANES                  *
  1688. ;* A0     = SrcBitmap    (on screen)               *
  1689. ;* A1     = DestBitMap    (off screen)              *
  1690. ;* A2     = TempA = NULL (bitmaps can't overlap)   *
  1691. ;* A6     = GfxBase                  *
  1692. ;**************************************************
  1693. ;   SrcX = Window->LeftEdge
  1694. LoadSwapData:    moveq.l     #0,D0
  1695.         move.w        wwd_LeftEdge(A0),D0
  1696.  
  1697. ;   SrcY = Window->TopEdge
  1698.         moveq.l     #0,D1
  1699.         move.w        wwd_TopEdge(A0),D1
  1700.  
  1701. ;   DestX = 0
  1702.         moveq.l     #0,D2
  1703.  
  1704. ;   DestY = 0
  1705.         moveq.l     #0,D3
  1706.  
  1707. ;   SizeX = Window->Width
  1708.         moveq.l     #0,D4
  1709.         move.w        wwd_Width(A0),D4
  1710.  
  1711. ;   SizeY = Window->Height
  1712.         moveq.l     #0,D5
  1713.         move.w        wwd_Height(A0),D5
  1714.  
  1715. ;   Mask = ALLPLANES
  1716.         moveq.l     #ALLPLANES,D7
  1717.  
  1718. ;   TempA = NULL
  1719.         sub.l        A2,A2
  1720.  
  1721.         move.l        _GfxBase(A4),A6
  1722.  
  1723. ;   Off-screen bitmap = Window->BitMap
  1724.         lea        wwd_Bm(A0),A1
  1725.  
  1726. ;   On-screen bitmap = Rp.BitMap (= Screen.BitMap)
  1727.         move.l        _Rp+rp_BitMap(A4),A0
  1728.  
  1729.         rts
  1730.  
  1731.  
  1732. ;*********************************************
  1733. ;* FindItemWinSize(Window,WindowType)        *
  1734. ;*                         *
  1735. ;* Find width and hight needed for all items *
  1736. ;*********************************************
  1737. @FindItemWinSize:
  1738.         move.l        A2,-(SP)
  1739.         move.l        D2,-(SP)
  1740.  
  1741. ;   SizeOk = FALSE
  1742.         moveq.l     #FALSE,D2
  1743.  
  1744. ;   Item = Window->Items
  1745.         move.l        wwd_Items(A0),A2
  1746.  
  1747. ;   Size.left = WORD_MAX
  1748.         move.w        #WORD_MAX,_Size+wws_Left(A4)
  1749.  
  1750. ;   Size.Top  = WindowType (ITEMWINDOW -> TopPos >= 0), SUBWINDOW -> no limit
  1751.         move.w        D0,_Size+wws_Top(A4)
  1752.  
  1753. ;   Size.Right = Size.bottom = WORD_MIN
  1754.         move.w        #WORD_MIN,D0
  1755.         move.w        D0,_Size+wws_Right(A4)
  1756.         move.w        D0,_Size+wws_Bottom(A4)
  1757.  
  1758. ;   Size.CommKey = 0
  1759.         move.w        D2,_Size+wws_CommKey(A4)
  1760.  
  1761. ;   SizeOk |= CheckItemSize(Item,Item->ItemFill)
  1762. 1$        move.l        A2,A0
  1763.         move.l        mi_ItemFill(A0),A1
  1764.         call        CheckItemSize
  1765.         or.l        D0,D2
  1766.  
  1767. ;   Item->Flags & HIGHFLAGS == HIGHIMAGE ?
  1768.         move.w        #HIGHFLAGS,D0
  1769.         and.w        mi_Flags(A2),D0
  1770.         bne        2$
  1771.  
  1772. ;   SizeOk |= CheckItemSize(Item,Item->SelectFill)
  1773.         move.l        A2,A0
  1774.         move.l        mi_SelectFill(A0),A1
  1775.         call        CheckItemSize
  1776.         or.l        D0,D2
  1777.  
  1778. ;   Check next item.
  1779. 2$        move.l        mi_NextItem(A2),A2
  1780.         move.l        A2,D0
  1781.         bne        1$
  1782.  
  1783. ;   return SizeOK
  1784.         move.l        D2,D0
  1785.  
  1786.         move.l        (SP)+,D2
  1787.         move.l        (SP)+,A2
  1788.         rts
  1789.  
  1790. ;*********************************************************
  1791. ;* CheckItemSize(Item,Contents) -                        *
  1792. ;*  find the size needed to include Item in window.     *
  1793. ;*                             *
  1794. ;* Input:                         *
  1795. ;*   Item      (A0)  Item to check.                      *
  1796. ;*   Contents  (A1)  What to fill (ItemFill/SelectFill). *
  1797. ;* Output:                         *
  1798. ;*   Size         New size of window          *
  1799. ;*   return         TRUE if anything is found.      *
  1800. ;*********************************************************
  1801. @CheckItemSize:
  1802. ;   Anything to check ?
  1803.         move.l        A1,D0
  1804.         bne        1$            ; Yes
  1805.         rts
  1806.  
  1807. 1$        movem.l     D2-D7/A2/A3/A5/A6,-(SP)
  1808.         lea        -te_SIZEOF(SP),SP
  1809.  
  1810.         move.l        A0,A2        ; A2 = Item to check
  1811.         move.l        A1,A5        ; A5 = What to check
  1812.         lea        _Size(A4),A3        ; A3 = SizeSoFar
  1813.  
  1814. ;   if item has command key check size of font
  1815. ;   Default size if ItemImage or no font specified
  1816.         moveq.l     #COMMSEQ,D0
  1817.         and.w        mi_Flags(A2),D0
  1818.         beq        Check        ; No CommKey
  1819.  
  1820.         move.w        _CommKeyWidth(A4),D3   ; deafult size
  1821.  
  1822.         moveq.l     #ITEMTEXT,D0
  1823.         and.w        mi_Flags(A2),D0
  1824.         beq        2$
  1825.  
  1826. ;   Command key uses same font as first IText string
  1827.         move.l        it_ITextFont(A5),D0
  1828.         beq        2$          ; No font specified
  1829.  
  1830. ;   Open the font
  1831.         move.l        _GfxBase(A4),A6
  1832.         move.l        D0,A0
  1833.         libcall     OpenFont      ; (A0=textAttr)
  1834.         move.l        D0,D2
  1835.         beq        2$          ; Font not resident
  1836.  
  1837. ;   FontExtent(TextFont,&ExtentData)
  1838.         move.l        D0,A0
  1839.         move.l        SP,A1
  1840.         libcall     FontExtent
  1841.  
  1842.         move.w        te_Extent+ra_MaxX(SP),D3
  1843.  
  1844. ;   Close the font again
  1845.         move.l        D2,A1
  1846.         libcall     CloseFont       ; (A1=textFont)
  1847.  
  1848. ;   Larger than current max ?  (SizeSoFar->CommKey)
  1849. 2$        cmp.w        wws_CommKey(A3),D3
  1850.         bls        Check
  1851.         move.w        D3,wws_CommKey(A3)
  1852.  
  1853. ;   ImTxLeft = ItemLeft = Item->LeftEdge
  1854. Check:        move.w        mi_LeftEdge(A2),D3
  1855.         move.w        D3,D7
  1856.  
  1857. ;   ImTxTop = ItemTop = Item->TopEdge
  1858.         move.w        mi_TopEdge(A2),D2
  1859.         move.w        D2,D6
  1860.  
  1861. ;   ITEMTEXT or ITEMIMAGE ?
  1862.         moveq.l     #ITEMTEXT,D0
  1863.         and.w        mi_Flags(A2),D0
  1864.         beq        ItemImage
  1865.  
  1866. ;   Add IText position to left and top.
  1867. ;   ImTxLeft += IText.leftEdge
  1868.         add.w        it_LeftEdge(A5),D7
  1869.  
  1870. ;   ImTxTop += IText.TopEdge
  1871.         add.w        it_TopEdge(A5),D6
  1872.  
  1873. ;   ImTxRight = ImTxLeft
  1874.         move.w        D7,D5
  1875.  
  1876. ;   ImTxBottom = ImTxTop
  1877.         move.w        D6,D4
  1878.  
  1879. ;   What font to use ?
  1880.         move.l        it_ITextFont(A5),D0
  1881.         beq        DefaultFont
  1882.  
  1883. ;   Add height and length of string.
  1884. ;   ImTxBottom += ITextFont->ta_YSize
  1885.         move.l        D0,A0
  1886.         add.w        ta_YSize(A0),D4
  1887.  
  1888. ;   ImTxRight += IntuiTextLength(IText)
  1889.         move.l        A5,A0
  1890.         move.l        _IntuitionBase(A4),A6
  1891.         libcall     IntuiTextLength
  1892.         add.w        D0,D5
  1893.  
  1894.         bra        NextText
  1895.  
  1896. ;   Add hight and length of string with default font.
  1897. ;   TextExtent(Rp,Itext,strlen(IText),&ExtentData)
  1898. DefaultFont:    move.l        A2,-(SP)
  1899.         move.l        it_IText(A5),A0
  1900.         call        Mystrlen
  1901.         lea        _Rp(A4),A1
  1902.         move.l        it_IText(A5),A0
  1903.         lea        4(SP),A2
  1904.         move.l        _GfxBase(A4),A6
  1905.         libcall     TextExtent
  1906.  
  1907. ;   ImTxBottom += te_Height
  1908.         add.w        te_Height(A2),D4
  1909.  
  1910. ;   ImTxRight += te_Extent.MaxX
  1911.         add.w        te_Extent+ra_MaxX(A2),D5
  1912.  
  1913.         move.l        (SP)+,A2
  1914.  
  1915. ;   Move to next text.
  1916. NextText:    move.l        it_NextText(A5),A5
  1917.         bra        CheckLeft
  1918.  
  1919. ;   ImTxLeft += Image.leftEdge
  1920. ItemImage:    add.w        ig_LeftEdge(A5),D7
  1921.  
  1922. ;   ImTxTop += Image.TopEdge
  1923.         add.w        ig_TopEdge(A5),D6
  1924.  
  1925. ;   ImTxRight = ImTxLeft + Image.width
  1926.         move.w        D7,D5
  1927.         add.w        ig_Width(A5),D5
  1928.  
  1929. ;   ImTxBottom = ImTxTop + Image.Height
  1930.         move.w        D6,D4
  1931.         add.w        ig_Height(A5),D4
  1932.  
  1933. ;   Move to next image
  1934.         move.l        ig_NextImage(A5),A5
  1935.  
  1936. ;   Compare with size in SizeSoFar
  1937. ;   ItemLeft = Min(ImTxLeft, ItemLeft)
  1938. CheckLeft:    cmp.w        D7,D3
  1939.         bge        1$
  1940.         move.w        D3,D7
  1941.  
  1942. ;   SizeSoFar.left = Min(SizeSoFar.left, ItemLeft)
  1943. 1$:        cmp.w        wws_Left(A3),D7
  1944.         bge        CheckRight
  1945.         move.w        D7,wws_Left(A3)
  1946.  
  1947. ;   ItemRight = Max(ItemLeft + Item.width, ImTxRight)
  1948. CheckRight:    add.w        mi_Width(A2),D3
  1949.         cmp.w        D5,D3
  1950.         ble        1$
  1951.         move.w        D3,D5
  1952.  
  1953. ;   SizeSoFar.Right = Max(SizeSoFar.Right, ItemRight)
  1954. 1$:        cmp.w        wws_Right(A3),D5
  1955.         ble        CheckTop
  1956.         move.w        D5,wws_Right(A3)
  1957.  
  1958. ;   ItemTop = Min(ItemTop, ImTxTop).
  1959. CheckTop:    cmp.w        D6,D2
  1960.         bge        1$
  1961.         move.w        D2,D6
  1962.  
  1963. ;   SizeSoFar.Top = Min(SizeSoFar.Top, ItemTop)
  1964. 1$        cmp.w        wws_Top(A3),D6
  1965.         bge        CheckBottom
  1966.         move.w        D6,wws_Top(A3)
  1967.  
  1968. ;   ItemBottom = Max(ItemLeft + Item.Height, ImTxBottom)
  1969. CheckBottom:    add.w        mi_Height(A2),D2
  1970.         cmp.w        D4,D2
  1971.         ble        1$
  1972.         move.w        D2,D4
  1973.  
  1974. ;   SizeSoFar.bottom = Max(SizeSoFar.bottom, ItemBottom)
  1975. 1$        cmp.w        wws_Bottom(A3),D4
  1976.         ble        2$
  1977.         move.w        D4,wws_Bottom(A3)
  1978.  
  1979. ;   Anything more to check
  1980. 2$        move.l        A5,D0
  1981.         bne        Check
  1982.  
  1983.         lea        te_SIZEOF(SP),SP
  1984.         moveq.l     #TRUE,D0
  1985.         movem.l     (SP)+,D2-D7/A2/A3/A5/A6
  1986.         rts
  1987.  
  1988. ;*****************************************
  1989. ;* SelectItem(VOID) - Do selection       *
  1990. ;*  Input:                 *
  1991. ;*  Output:                 *
  1992. ;*    return    - Selected Item or NULL  *
  1993. ;*****************************************
  1994. @SelectItem:    movem.l     D2/D3/A2/A3/A5,-(SP)
  1995. ;********************
  1996. ;* Check subwindow. *
  1997. ;********************
  1998. ;   SubWindow.bitMapOk == TRUE ?
  1999.         lea        _SubWindow(A4),A2
  2000.         tst.w        wwd_BitMapOk(A2)
  2001.         beq        CheckItem      ; Not open
  2002.  
  2003. ;   Mouse in SubWindow ?
  2004.         move.l        A2,A0
  2005.         call        MouseInWindow
  2006.         tst.w        D0
  2007.         beq        2$         ; Not in window
  2008.  
  2009. ;   NewSubItem = FindMouseItem(&SubWindow)
  2010.         move.l        A2,A0
  2011.         call        FindMouseItem
  2012.         move.l        D0,A3
  2013.  
  2014. ;   Anything changed ? [NewSubItem == SubWindow.Current]
  2015.         move.l        wwd_Current(A2),A0
  2016.         cmp.l        A0,A3
  2017.         beq        SelectDone      ; Nothing changed
  2018.  
  2019. ;***********************
  2020. ;* A0 = CurrentSubItem *
  2021. ;* A2 = SubWindow      *
  2022. ;* A3 = NewSubItem     *
  2023. ;***********************
  2024. ;   SubWindow.Current == NULL ? [Anything highlighted]
  2025.         move.l        A0,D0
  2026.         beq        1$          ; Yes
  2027.  
  2028. ;   HighLightItem(&SubWindow,HIGHLIGHTOFF)
  2029.         moveq.l     #HIGHLIGHTOFF,D0       ; [HIGHLIGHTOFF = TRUE]
  2030.         move.l        A2,A0
  2031.         call        HighLightItem
  2032.  
  2033. ;   SubWindow.Current = NewSubItem.
  2034. 1$        move.l        A3,wwd_Current(A2)
  2035.  
  2036. ;   SubWindow.Current == NULL ?
  2037.         beq        SelectDone       ; Yes
  2038.  
  2039. ;   HighLightItem(&SubWindow,HIGHLIGHTON)
  2040.         moveq.l     #HIGHLIGHTON,D0       ; [HIGHLIGHTON = FALSE]
  2041.         move.l        A2,A0
  2042.         call        HighLightItem
  2043.  
  2044. ;   Selectable item ?
  2045.         tst.w        D0
  2046.         beq        SelectDone      ; No
  2047.  
  2048. ;   return NewSubItem
  2049.         moveq.l     #TRUE,D0
  2050.         bra        SelectQuit
  2051.  
  2052. ;   Anything highlighted
  2053. 2$        move.l        wwd_Current(A2),A0
  2054.         move.l        A0,D0
  2055.         beq        CheckItem
  2056.  
  2057. ;   HighLightItem(&SubWindow,HIGHLIGHTOFF)
  2058.         move.l        A2,A0
  2059.         moveq.l     #HIGHLIGHTOFF,D0
  2060.         call        HighLightItem
  2061.  
  2062. ;   SubWindow.Current = NULL
  2063.         clr.l        wwd_Current(A2)
  2064.  
  2065. ;*********************
  2066. ;* Check itemwindow. *
  2067. ;*********************
  2068. ;   ItemWindow.bitMapOk == TRUE ?
  2069. CheckItem:    lea        _ItemWindow(A4),A3
  2070.         tst.w        wwd_BitMapOk(A3)
  2071.         beq        CheckMenu      ; No
  2072.  
  2073. ;   Mouse in ItemWindow ?
  2074.         move.l        A3,A0
  2075.         call        MouseInWindow
  2076.         tst.w        D0
  2077.         beq        3$          ; No
  2078.  
  2079. ;   NewItem = FindMouseItem(&ItemWindow).
  2080.         move.l        A3,A0
  2081.         call        FindMouseItem
  2082.         move.l        D0,A5
  2083.  
  2084.         move.l        wwd_Current(A3),D2
  2085.  
  2086. ;***************************************
  2087. ;* A2 = SubWindow     D2 = CurrentItem *
  2088. ;* A3 = ItemWindow               *
  2089. ;* A5 = NewItem                *
  2090. ;***************************************
  2091. ;   NewItem == CurrentItem ?
  2092.         cmp.l        D2,A5
  2093.         beq        SelectDone      ; Yes
  2094.  
  2095. ;   CurrentItem == NULL ?
  2096.         tst.l        D2
  2097.         beq        2$          ; Yes
  2098.  
  2099. ;   SubWindow open ?
  2100.         tst.w        wwd_BitMapOk(A2)
  2101.         beq        1$          ; No
  2102.  
  2103. ;   CloseSubWindow()
  2104.         call        CloseSubWindow
  2105.  
  2106. ;   HighLightItem(&ItemWindow,HIGHLIGHTOFF)
  2107. 1$        moveq.l     #HIGHLIGHTOFF,D0
  2108.         move.l        A3,A0
  2109.         call        HighLightItem
  2110.  
  2111. ;   ItemWindow.Current = NewItem.
  2112. 2$        move.l        A5,_ItemWindow+wwd_Current(A4)
  2113.  
  2114. ;   NewItem == NULL ?
  2115.         move.l        A5,D2
  2116.         beq        SelectDone      ; Yes
  2117.  
  2118. ;   HighLightItem(&ItemWindow,HIGHLIGHTON)
  2119.         moveQ        #0,D0
  2120.         move.l        A3,A0
  2121.         call        HighLightItem
  2122.  
  2123. ;   SubWindow.ItemsEnabled = ItemWindow.ItemsEnabled ?
  2124. ;    (NewItem->Flags & ITEMENABLED) : 0
  2125.         move.w        _ItemWindow+wwd_ItemsEnabled(A4),D1
  2126.         beq        25$
  2127.         moveq.l     #ITEMENABLED,D1
  2128.         and.w        mi_Flags(A5),D1
  2129. 25$        move.w        D1,_SubWindow+wwd_ItemsEnabled(A4)
  2130.  
  2131. ;   SubWindow.Items = NewItem->SubItem.
  2132.         move.l        mi_SubItem(A5),_SubWindow+wwd_Items(A4)
  2133.  
  2134. ;   SubWindow.Items == NULL ?
  2135.         bne        28$       ; No
  2136.  
  2137. ;   Possible to highlight item ?
  2138.         tst.w        D0
  2139.         beq        SelectDone      ; No
  2140.  
  2141. ;   return TRUE
  2142.         moveq.l     #TRUE,D0
  2143.         bra        SelectQuit
  2144.  
  2145. ;   Open item window
  2146. ;   OpenItemWindow(SubWindow,SUBWINDOW,
  2147. ;     CurrentItem->LeftEdge - ItemWindow->LeftValue,
  2148. ;     CurrentItem->LeftEdge + CurrentItem->Width - ItemWindow->LeftValue,
  2149. ;     CurrentItem->TopEdge - ItemWindow->TopValue)
  2150. 28$        move.w        #SUBWINDOW,D0
  2151.         move.l        D2,A0
  2152.         move.w        mi_LeftEdge(A0),D1
  2153.         sub.w        _ItemWindow+wwd_LeftValue(A4),D1
  2154.         move.w        D1,D2
  2155.         add.w        mi_Width(A0),D2
  2156.         move.w        mi_TopEdge(A0),D3
  2157.         sub.w        _ItemWindow+wwd_TopValue(A4),D3
  2158.         move.l        A2,A0
  2159.         call        OpenItemWindow
  2160.  
  2161. ;   Window opened ?
  2162.         tst.w        D0
  2163.         beq        29$       ; No
  2164.  
  2165. ;   Set ISDRAWN bit  [ NewItem.Flags |= ISDRAWNBIT ]
  2166.         bset        #ISDRAWN_B0,mi_Flags(A5)
  2167.  
  2168. 29$        bra        SelectDone
  2169.  
  2170. ;   ItemWindow.Current == NULL ?
  2171. 3$        tst.l        wwd_Current(A3)
  2172.         beq        CheckMenu      ; Yes
  2173.  
  2174. ;   SubWindow open ?
  2175.         tst.w        wwd_BitMapOk(A2)
  2176.         bne        CheckMenu      ; Yes
  2177.  
  2178. ;   HighLightItem(&ItemWindow,HIGHLIGHTOFF)
  2179. 4$        moveq.l     #HIGHLIGHTOFF,D0
  2180.         move.l        A3,A0
  2181.         call        HighLightItem
  2182.  
  2183. ;   ItemWindow.Current = NULL.
  2184.         clr.l        wwd_Current(A3)
  2185.  
  2186. ;*********************
  2187. ;* Check menuwindow. *
  2188. ;*********************
  2189. CheckMenu:    lea        _MenuWindow(A4),A5
  2190.  
  2191. ;**********************
  2192. ;* A2 = SubWindow     *
  2193. ;* A3 = ItemWindow    *
  2194. ;* A5 = MenuWindow    *
  2195. ;**********************
  2196. ;   MenuWindow.bitMapOK ?
  2197.         tst.w        wwd_BitMapOk(A5)
  2198.         beq        SelectDone      ; No
  2199.  
  2200. ;   MouseInWindow(MenuWindow) ?
  2201.         move.l        A5,A0
  2202.         call        MouseInWindow
  2203.         tst.w        D0
  2204.         beq        SelectDone      ; No
  2205.  
  2206. ;   NewMenuNr = (MouseY - MenuWindow.TopEdge - HBORDERSIZE)/MenuTextHeight + 1
  2207. ;   NewMenuNr = NewMenuNr < 0 ? 0 : NewMenuNr
  2208.         moveq.l     #0,D2
  2209.         move.w        _MouseY(A4),D2
  2210.         sub.w        wwd_TopEdge(A5),D2
  2211.         subq.w        #HBORDERSIZE,D2
  2212.         bpl        05$
  2213.         moveq.l     #1,D2
  2214.         bra        07$
  2215. 05$        divu.w        _MenuTextHeight(A4),D2
  2216.         addq.w        #1,D2
  2217.  
  2218. ;   NewMenuNr == CurrentMenuNr ?
  2219. 07$        move.w        _CurrentMenuNr(A4),D3
  2220.         cmp.w        D3,D2
  2221.         beq        SelectDone      ; Yes
  2222.  
  2223. ;****************************************
  2224. ;* A2 = SubWindow    D2 = NewMenuNr    *
  2225. ;* A3 = ItemWindow   D3 = CurrentMenuNr *
  2226. ;* A5 = MenuWindow            *
  2227. ;****************************************
  2228. ;   CurrentMenuNr == 0 ?
  2229.         tst.w        D3
  2230.         beq        2$          ; Yes
  2231.  
  2232. ;   ItemWindow.bitMapOk
  2233.         tst.w        wwd_BitMapOk(A3)
  2234.         beq        1$          ; No
  2235.  
  2236. ;   Close sub and item windows
  2237.         call        CloseSubWindow
  2238.         call        CloseItemWindow
  2239.  
  2240. ;   ToggleMenu(CurrentMenuNr,MenuWindow.Current) - HIGHLIGHTOFF -
  2241. 1$        move.w        D3,D0
  2242.         move.l        wwd_Current(A5),A0
  2243.         call        ToggleMenu
  2244.  
  2245. ;   MenuWindow.Current = FindMenuPtr(NewMenuNr)
  2246. 2$        lea        _MenuSorted-4(A4),A0
  2247.         move.w        D2,D0
  2248.         lsl.w        #2,D0
  2249.         move.l        0(A0,D0.w),wwd_Current(A5)
  2250.  
  2251. ;   MenuWindow.Current == NULL ?
  2252.         bne        3$          ; No
  2253.  
  2254. ;   CurrentMenuNr = 0
  2255.         clr.w        _CurrentMenuNr(A4)
  2256.         bra        SelectDone
  2257.  
  2258. ;   CurrentMenuNr = LastSelectedNum = NewMenuNr
  2259. 3$        move.w        D2,_CurrentMenuNr(A4)
  2260.         move.w        D2,_LastSelectedNum(A4)
  2261.         move.w        D2,D3
  2262.  
  2263. ;   ItemWindow.ItemsEnabled = MenuWindow.Current->Flags & MENUENABLED
  2264.         move.l        wwd_Current(A5),A0
  2265.         moveq.l     #MENUENABLED,D0
  2266.         and.w        mu_Flags(A0),D0
  2267.         move.w        D0,wwd_ItemsEnabled(A3)
  2268.  
  2269. ;   ItemWindow.Items = MenuWindow.Current->FirstItem
  2270.         move.l        mu_FirstItem(A0),wwd_Items(A3)
  2271.  
  2272. ;   ToggleMenu(NewMenuNr,MenuWindow.Current)  - HIGHLIGHTON -
  2273.         move.w        D2,D0
  2274.         call        ToggleMenu
  2275.  
  2276. ;   ItemWindow->Items == NULL ?
  2277.         tst.l        wwd_Items(A3)
  2278.         beq        SelectDone      ; Yes
  2279.  
  2280. ;   ItemsTopPos = (CurrentMenuNr - 1) * MenuTextHeight + MenuWindow.TopEdge + HBORDERSIZE
  2281.         subq.w        #1,D3
  2282.         mulu.w        _MenuTextHeight(A4),D3
  2283.         add.w        _MenuWindow+wwd_TopEdge(A4),D3
  2284.         addq.w        #HBORDERSIZE,D3
  2285.  
  2286. ;   OpenItemWindow(ItemWindow,ITEMWINDOW,
  2287. ;           MenuWindow.leftEdge, MenuWindow.RightEdge, ItemsTopPos)
  2288.         move.l        A3,A0
  2289.         moveq.l     #ITEMWINDOW,D0
  2290.         moveq.l     #0,D1
  2291.         move.w        _MenuWindow+wwd_LeftEdge(A4),D1
  2292.         moveq.l     #0,D2
  2293.         move.w        _MenuWindow+wwd_RightEdge(A4),D2
  2294.         call        OpenItemWindow
  2295.  
  2296. ;   Window opened ?
  2297.         tst.w        D0
  2298.         beq        SelectDone      ; NO
  2299.  
  2300. ;   Set MIDRAWN flag
  2301.         move.l        wwd_Current(A5),A0
  2302.         bset        #MIDRAWN_B0,mu_Flags(A0)
  2303.  
  2304. SelectDone:    moveq.l     #FALSE,D0
  2305. SelectQuit:    movem.l     (SP)+,D2/D3/A2/A3/A5
  2306.         rts
  2307.  
  2308. ;*****************************************************************
  2309. ;* FinalSelect() - Do checkmarking and calculate Menupick value. *
  2310. ;*                                 *
  2311. ;* Input:                             *
  2312. ;*   none                             *
  2313. ;* Output:                             *
  2314. ;*   return  - MenuPick-value or MENUNULL.             *
  2315. ;*****************************************************************
  2316. @FinalSelect:    move.l        D2,-(SP)
  2317.  
  2318. ;   SubItemNr = NOSUB
  2319.         moveq.l     #NOSUB,D2
  2320.  
  2321. ;   SubWindow.Current == NULL ?
  2322.         move.l        _SubWindow+wwd_Current(A4),D0
  2323.         beq        1$          ; Yes
  2324.  
  2325.         move.l        D0,A0
  2326.  
  2327. ;   SubWindow.Current->Flags & SubWindow.ItemsEnabled & ITEMENABLED ?
  2328.         move.w        mi_Flags(A0),D1
  2329.         moveq.l     #ITEMENABLED,D0
  2330.         and.w        D1,D0
  2331.         and.w        _SubWindow+wwd_ItemsEnabled(A4),D0
  2332.         beq        2$          ; No
  2333.  
  2334. ;   SubWindow.Current->Flags & MENUTOGGLED ?
  2335.         btst        #MENUTOGGLED_B0+8,D1
  2336.         bne        2$          ; Yes
  2337.  
  2338. ;   Find the number of the selected subitem
  2339.         move.l        _SubWindow+wwd_Items(A4),A1
  2340.         call        FindItemNr
  2341.  
  2342.         and.w        #NOSUB,D0      ; NOITEM > NOSUB
  2343.         move.l        D0,D2
  2344.  
  2345. ;   Subitem selected -> checkmark and draw all subitems again.
  2346. ;   CheckMark(&SubWindow)
  2347.         lea        _SubWindow(A4),A0
  2348.         call        CheckMark
  2349.  
  2350. ;   Anything changed ?
  2351.         tst.w        D0
  2352.         beq        3$     ; No
  2353.  
  2354. ;   DrawAllItems(&SubWindow)
  2355.         lea        _SubWindow(A4),A0
  2356.         call        DrawAllItems
  2357.  
  2358. ;   HighLightItem(&SubWindow,HIGHLIGHTON)
  2359.         moveq.l     #HIGHLIGHTON,D0
  2360.         lea        _SubWindow(A4),A0
  2361.         call        HighLightItem
  2362.         bra        3$
  2363.  
  2364. ;   ItemWindow.Current == NULL ?
  2365. 1$        move.l        _ItemWindow+wwd_Current(A4),D0
  2366.         beq        2$          ; Yes
  2367.  
  2368.         move.l        D0,A0
  2369.  
  2370. ;   ItemWindow.Current->SubItem == NULL ?
  2371.         tst.l        mi_SubItem(A0)
  2372.         bne        2$          ; No
  2373.  
  2374. ;   ItemWindow.Current->Flags & ITEMENABLED ?
  2375.         move.w        mi_Flags(A0),D1
  2376.         btst        #ITEMENABLED_B1,D1
  2377.         beq        2$          ; No
  2378.  
  2379. ;   ItemWindow.Current->Flags & MENUTOGGLED ?
  2380.         btst        #MENUTOGGLED_B0+8,D1
  2381.         bne        2$          ; Yes
  2382.  
  2383. ;   ItemWindow.ItemsEnabled & MENUENABLED ?
  2384.         tst.w        _ItemWindow+wwd_ItemsEnabled(A4)
  2385.         bne        3$          ; Yes
  2386.  
  2387. ;   Nothing is selected -> exit
  2388. 2$        moveq.l     #-1,D0      ; MENUNULL
  2389.         bra        6$
  2390.  
  2391. ;   CheckMark(ItemWindow)
  2392. 3$        lea        _ItemWindow(A4),A0
  2393.         call        CheckMark
  2394.         tst.w        D0
  2395.         beq        38$
  2396.  
  2397. ;   Remove SubWindow (if any).
  2398.         lea        _SubWindow(A4),A0
  2399.         call        SwapBits
  2400.  
  2401. ;   DrawAllItems(&ItemWindow)
  2402.         lea        _ItemWindow(A4),A0
  2403.         call        DrawAllItems
  2404.  
  2405. ;   Check if ItemWindow & MenuWindow is Same (4.0)
  2406.         tst.w        _MenuWindow+wwd_BitMapOk(A4)
  2407.         bne        35$
  2408.  
  2409. ;   DrawAllMenus(ItemWindow)
  2410.         lea        _ItemWindow(A4),A0
  2411.         call        DrawAllMenus
  2412.  
  2413. ;   HighLightItem(&ItemWindow,HIGHLIGHTON)
  2414. 35$        moveq.l     #HIGHLIGHTON,D0
  2415.         lea        _ItemWindow(A4),A0
  2416.         call        HighLightItem
  2417.  
  2418. ;   Restore subwindow. (if any)
  2419.         lea        _SubWindow(A4),A0
  2420.         call        SwapBits
  2421.  
  2422. ;   Find number of selected item,
  2423. 38$        move.l        _ItemWindow+wwd_Current(A4),A0
  2424.         move.l        _ItemWindow+wwd_Items(A4),A1
  2425.         call        FindItemNr
  2426.  
  2427. ;   MenuNum = SHIFTMENU(FindRealMenuNum(CurrentMenuNr)) |
  2428. ;          SHIFTITEM(ItemNr) |
  2429. ;          SHIFTSUB(SubItemNr)
  2430.         lsl.w        #6,D2
  2431.         or.w        D2,D0
  2432.         lsl.w        #5,D0
  2433.  
  2434.         lea        _MenuSorted-4(A4),A0
  2435.         move.w        _CurrentMenuNr(A4),D1
  2436.         lsl.w        #2,D1
  2437.         move.l        0(A0,D1.W),A1
  2438.  
  2439.         move.l        _Menus(A4),A0
  2440.         bra        5$
  2441.  
  2442. 4$        move.l        mu_NextMenu(A0),A0
  2443.         addq.w        #1,D0
  2444.  
  2445. 5$        cmp.l        A0,A1
  2446.         bne        4$
  2447.  
  2448. 6$        move.l        (SP)+,D2
  2449.         rts
  2450.  
  2451. ;*****************************************************
  2452. ;* BOOL CheckMark(Window) - Checkmark selected item. *
  2453. ;*                             *
  2454. ;* Input:                         *
  2455. ;*   Window    - Window to checkmark             *
  2456. ;* Output:                         *
  2457. ;*   return.w    - TRUE if checkmarked             *
  2458. ;*****************************************************
  2459. @CheckMark:    move.l        wwd_Items(A0),A1
  2460.         move.l        wwd_Current(A0),A0
  2461.  
  2462.         moveq.l     #FALSE,D0
  2463.         move.w        mi_Flags(A0),D1
  2464.  
  2465. ;   Selected->Flags & CHECKIT ?
  2466.         btst        #CHECKIT_B1,D1
  2467.         beq        4$          ; No
  2468.  
  2469. ;   Selected->Flags & CHECKED ?
  2470.         btst        #CHECKED_B0+8,D1
  2471.         beq        1$          ; No
  2472.  
  2473. ;   Selected->Flags & MENUTOGGLE ?
  2474.         btst        #MENUTOGGLE_B1,D1
  2475.         beq        4$          ; No
  2476.  
  2477. ;   Selected->Flags &= ~CHECKED   - Togglemenu -
  2478.         bclr        #CHECKED_B0,mi_Flags(A0)
  2479.         bra        35$
  2480.  
  2481. ;   Selected->Flags |= CHECKED
  2482. 1$        bset        #CHECKED_B0,mi_Flags(A0)
  2483.  
  2484. ;   Handle mutual exclusion.
  2485. ;   Exclude = Selected->MutualExclude
  2486.         move.l        mi_MutualExclude(A0),D0
  2487.         beq        35$
  2488.  
  2489. ;   Exclude >>= 1
  2490. 2$        lsr.l        #1,D0
  2491.         bcc        3$
  2492.  
  2493. ;   Items->Flags &= ~CHECKED
  2494.         bclr        #CHECKED_B0,mi_Flags(A1)
  2495.  
  2496. ;   Items = Items->NextItem
  2497. 3$        move.l        mi_NextItem(A1),A1
  2498.  
  2499. ;   More items ?
  2500.         move.l        A1,D1
  2501.         bne        2$           ; Yes
  2502.  
  2503. 35$        moveq.l     #TRUE,D0
  2504. 4$        rts
  2505.  
  2506. *************************************************************
  2507. * VOID DrawMenuItem(Window, Item, Mode)                     *
  2508. *                                *
  2509. * Input:                            *
  2510. *   Window  -      Data about window to draw item into.        *
  2511. *   Item    -      Item to draw.                 *
  2512. *   Mode.w  -      ITEMFILL = Draw Item.             *
  2513. *          SELECTFILL = Draw selected item (if any). *
  2514. * OUTPUT                            *
  2515. *   none                            *
  2516. *************************************************************
  2517. @DrawMenuItem:    movem.l     D2-D7/A2/A3/A5/A6,-(SP)
  2518.         move.l        A1,A3
  2519.  
  2520.         move.l        A0,-(SP)
  2521. ********************************************************
  2522. * D0 = Mode          A0 = Window       (SP) Window *
  2523. *              A1 = Item                *
  2524. *              A3 = Item                *
  2525. ********************************************************
  2526. ;   Left = Item->LeftEdge - Window->LeftValue
  2527.         move.w        mi_LeftEdge(A3),D7
  2528.         sub.w        wwd_LeftValue(A0),D7
  2529.         ext.l        D7
  2530.  
  2531. ;   Right = Left + Item->Width - 1
  2532.         move.l        D7,D2
  2533.         add.w        mi_Width(A3),D2
  2534.         subq.l        #1,D2
  2535.  
  2536. ;   ItemTop = Top = Item->TopEdge - Window->TopValue
  2537.         move.w        mi_TopEdge(A3),D6
  2538.         sub.w        wwd_TopValue(A0),D6
  2539.         ext.l        D6
  2540.         move.l        D6,D4
  2541.  
  2542. ;   Bottom = Top + Item->Height - 1
  2543.         move.l        D6,D3
  2544.         add.w        mi_Height(A3),D3
  2545.         subq.l        #1,D3
  2546.  
  2547.         lea        _Rp(A4),A5
  2548.         move.l        _IntuitionBase(A4),A6
  2549.  
  2550. ;   Find what to Draw.
  2551.         move.l        mi_ItemFill(A3),A2
  2552.  
  2553.         tst.w        D0          ; Mode == ITEMFILL ?
  2554.         beq        CheckDraw
  2555.  
  2556. ;   Use selectfill.
  2557.         move.l        mi_SelectFill(A3),A2
  2558.  
  2559. ***************************************************************
  2560. * D0 = Mode             A0 = Window      (SP) Window *
  2561. *                 A1 = Item                  *
  2562. * D2 = Right             A2 = Fill                  *
  2563. * D3 = Bottom             A3 = Item                  *
  2564. * D4 = ItemTop                              *
  2565. * D6 = Top             A5 = Rp                  *
  2566. * D7 = Left             A6 = IntuitionBase           *
  2567. ***************************************************************
  2568. ;   Anything to draw ?
  2569. CheckDraw:    move.l        A2,D0
  2570.         beq        DrawDone
  2571.  
  2572. ;   Draw the item.
  2573. DrawItem:    move.l        A5,A0           ; Rp
  2574.         move.l        A2,A1           ; Fill
  2575.         move.l        D7,D0           ; Left
  2576.         move.l        D6,D1           ; Top
  2577.  
  2578.         moveq.l     #ITEMTEXT,D5
  2579.         and.w        mi_Flags(A3),D5
  2580.         beq        DrawImage
  2581.  
  2582. ;   PrintIText(Fill, Left, Top)
  2583.         libcall     PrintIText
  2584.  
  2585. ;   ItemTop  += Fill.TopEdge
  2586.         add.w        it_TopEdge(A2),D4
  2587.  
  2588.         bra        DrawCheckMark
  2589.  
  2590. ;   DrawImage(Fill, Left, Top)
  2591. DrawImage:    libcall     DrawImage
  2592.  
  2593. ;   ItemTop += Fill.TopEdge
  2594.         add.w        ig_TopEdge(A2),D4
  2595.  
  2596. ***********************************************************
  2597. * D2 = Right         A2 = Fill          (SP) Window *
  2598. * D3 = Bottom         A3 = Item              *
  2599. * D4 = ItemTop         A5 = Rp              *
  2600. * D6 = Top         A6 = IntuitionBase          *
  2601. * D7 = Left                          *
  2602. ***********************************************************
  2603. ;   Draw CheckMark ?
  2604. DrawCheckMark:    btst        #CHECKIT_B1,mi_Flags+1(A3)
  2605.         beq        DrawCommKey
  2606.         btst        #CHECKED_B0,mi_Flags(A3)
  2607.         beq        DrawCommKey
  2608.  
  2609. ;   DrawImage(ActiveWindow->CheckMark, Left, ItemTop)
  2610.         move.l        _ActiveWindow(A4),A0
  2611.         move.l        wd_CheckMark(A0),A1   ; CheckMark
  2612.         move.l        D7,D0               ; Left
  2613.         move.l        D4,D1               ; ItemTop (New 3.7)
  2614.         move.l        A5,A0               ; Rp
  2615.         libcall     DrawImage
  2616.  
  2617. ***********************************************************
  2618. * D2 = Right         A2 = Fill         (SP)  Window *
  2619. * D3 = Bottom         A3 = Item              *
  2620. * D4 = ItemTop         A5 = Rp              *
  2621. * D6 = Top         A6 = IntuitionBase          *
  2622. * D7 = Left                          *
  2623. ***********************************************************
  2624. ;   Restore DrawMode   [SetDrMd(JAM1)]
  2625. DrawCommKey:    move.l        _GfxBase(A4),A6
  2626.         move.l        A5,A1               ; Rp
  2627.         moveq.l     #RP_JAM1,D0
  2628.         libcall     SetDrMd    ; (A1=rastPort,D0=drawmode)
  2629.  
  2630. ;   Has item a commad key ?
  2631.         moveq.l     #COMMSEQ,D0
  2632.         and.w        mi_Flags(A3),D0
  2633.         beq        GhostItem    ; No
  2634.  
  2635. ;   D5 = OldFont (NULL if default)
  2636.         moveq.l     #NULL,D5
  2637.  
  2638. ;   Find font to use
  2639.         moveq.l     #ITEMTEXT,D0
  2640.         and.w        mi_Flags(A3),D0
  2641.         beq        DefaultCommKey     ; ITEMIMAGE => Use default font
  2642.  
  2643.         move.l        mi_ItemFill(A3),D0   ; no itemfill => Use default font
  2644.         beq        DefaultCommKey
  2645.  
  2646.         move.l        D0,A0
  2647.         move.l        it_ITextFont(A0),D0
  2648.         beq        DefaultCommKey     ; No font specified => Use default
  2649.  
  2650. ;   We have to open the font to use.
  2651.         move.l        D0,A0
  2652.         libcall     OpenFont    ; (A0=textAttr)
  2653.  
  2654.         tst.l        D0
  2655.         beq        DefaultCommKey ; Font is not resident => use default symbol position
  2656.  
  2657.         move.l        rp_Font(A5),D1
  2658.         cmp.l        D0,D1
  2659.         bne        10$
  2660.  
  2661. ;   Same as deafult font
  2662.         move.l        D0,A1        ; Same as default
  2663.         libcall     CloseFont    ; (A1=textFont)
  2664.         bra        DefaultCommKey
  2665.  
  2666. 10$        move.l        D1,D5        ; D5 = OldFont
  2667.         move.l        D0,A0
  2668.         move.l        A5,A1
  2669.         libcall     SetFont    ; (A1=rastPort,A0=textFont)
  2670.  
  2671. ***********************************************************
  2672. * D2 = Right         A2 = Fill         (SP)  Window *
  2673. * D3 = Bottom         A3 = Item              *
  2674. * D4 = ItemTop         A5 = Rp              *
  2675. * D5 = OldFont                          *
  2676. * D6 = Top         A6 = GfxBase              *
  2677. * D7 = Left                          *
  2678. ***********************************************************
  2679. ;   SetAPen(DetailPen)
  2680. DefaultCommKey: moveq.l     #0,D0
  2681.         move.b        _DetailPen(A4),D0
  2682.         move.l        A5,A1
  2683.         libcall     SetAPen    ; (A1=rastPort,D0=pennum)
  2684.  
  2685. ;   KeyLeft = Right - Window->CommKeySize
  2686.         move.l        D2,D0
  2687.         move.l        (SP),A0
  2688.         sub.w        wwd_CommKeySize(A0),D0
  2689.  
  2690. ;   KeyTop = ItemTop + Rp.TxBaseLine;
  2691.         move.l        D4,D1
  2692.         add.w        rp_TxBaseline(A5),D1
  2693.  
  2694. ;   Move(KeyLeft,KeyTop)
  2695.         move.l        D0,-(SP)
  2696.         move.l        D1,-(SP)
  2697.         move.l        A5,A1
  2698.         libcall     Move        ; (A1=rastPort,D0=x,D1=y)
  2699.  
  2700. ;   Text(Rp,Item->Command,1)
  2701.         move.l        A5,A1
  2702.         lea        mi_Command(A3),A0
  2703.         moveq.l     #1,D0
  2704.         libcall     Text        ; (A1=rastPort,A0=stringPointer,D0=count)
  2705.  
  2706. ;   KeyTop -= AMIGAKEYHEIGHT-1
  2707.         move.l       (SP)+,D1
  2708.         move.l       (SP)+,D0
  2709.         subq.l       #AMIGAKEYHEIGHT-1,D1
  2710.  
  2711. ;   if (KeyTop < ItemTop) KeyTop = ItemTop
  2712.         cmp.w       D1,D4
  2713.         ble       1$
  2714.         move.l       D4,D1
  2715.  
  2716. ;   DrawImage(Rp,MyAmigaKeyImage[ScreenType], KeyLeft, KeyTop);
  2717. 1$        move.l       _IntuitionBase(A4),A6
  2718.         move.l       A5,A0
  2719.         lea       MyAmigaKeyImage(PC),A1
  2720.         tst.w       _ScreenType(A4)
  2721.         beq       2$
  2722.         lea       ig_SIZEOF(A1),A1
  2723. 2$        libcall    DrawImage    ; (A0=rastPort,A1=image,D0=leftOffset,D1=topOffset)
  2724.  
  2725.         move.l       _GfxBase(A4),A6
  2726.  
  2727. ;   Restore old font ?
  2728.         tst.l       D5
  2729.         beq       GhostItem
  2730.  
  2731. ;   Close the new font
  2732.         move.l       rp_Font(A5),A1
  2733.         libcall    CloseFont     ; (A1=textFont)
  2734.  
  2735.         move.l       D5,A0
  2736.         move.l       A5,A1
  2737.         libcall    SetFont     ; (A1=rastPort,A0=textFont)
  2738.  
  2739. ***********************************************************
  2740. * D2 = Right             A2 = Fill        (SP) = Window *
  2741. * D3 = Bottom             A3 = Item              *
  2742. * D4 = ItemTop             A5 = Rp              *
  2743. * D6 = Top             A6 = GfxBase          *
  2744. * D7 = Left                          *
  2745. ***********************************************************
  2746. ;   Ghost Item ?
  2747. GhostItem:    moveq.l     #ITEMENABLED,D0
  2748.         and.w        mi_Flags(A3),D0
  2749.         beq        1$
  2750.  
  2751.         move.l        (SP),A2
  2752.         tst.w        wwd_ItemsEnabled(A2)
  2753.         bne        DrawDone
  2754.  
  2755. ;   SetAfPt(&Rp, GhostPattern, 1)
  2756. 1$        lea        GhostPattern(PC),A0
  2757.         move.l        A0,_Rp+rp_AreaPtrn(A4)
  2758.  
  2759.         moveq.l     #1,D0
  2760.         move.b        D0,_Rp+rp_AreaPtSz(A4)
  2761.  
  2762. ;   SetAPen(BlockPen)
  2763.         move.b        _BlockPen(A4),D0
  2764.         move.l        A5,A1
  2765.         libcall     SetAPen    ; (A1=rastPort,D0=pennum)
  2766.  
  2767. ;   RectFill(Left, Top, Right, Bottom)
  2768.         move.l        A5,A1
  2769.         move.l        D7,D0
  2770.         move.l        D6,D1
  2771.         libcall     RectFill
  2772.  
  2773. ;   SetAfPt(NormalPattern, 1)
  2774.         lea        NormalPattern(PC),A0
  2775.         move.l        A0,_Rp+rp_AreaPtrn(A4)
  2776.  
  2777. DrawDone:    addq.l        #4,SP    ; forget Window
  2778.  
  2779.         movem.l     (SP)+,D2-D7/A2/A3/A5/A6
  2780.         rts
  2781.  
  2782. ***************************************************
  2783. * BOOL HighLightItem(Window, Mode)                *
  2784. *                          *
  2785. * Input:                      *
  2786. *   Window     -  Data for the window to draw in. *
  2787. *   Mode.w     -  HIGHLIGHTON or HIGHLIGHTOFF.      *
  2788. * Output:                      *
  2789. *   return     -  TRUE if item highlighted      *
  2790. *          (may be HIGHNONE)               *
  2791. ***************************************************
  2792. @HighLightItem: movem.l     D2-D4/A2/A3/A5/A6,-(SP)
  2793.  
  2794.         move.l        wwd_Current(A0),A3
  2795.  
  2796. ;   Possible to highlight item ?
  2797.         move.w        mi_Flags(A3),D4
  2798.         btst        #ITEMENABLED_B1,D4
  2799.         beq        1$              ; No
  2800.  
  2801.         tst.w        wwd_ItemsEnabled(A0)
  2802.         bne        15$           ; Yes
  2803.  
  2804. ;   return FALSE
  2805. 1$        moveq.l     #FALSE,D0
  2806.         bra        HighLightQuit
  2807.  
  2808. ;   start highlighting
  2809. 15$        move.l        A0,A2
  2810.  
  2811.         lea        _Rp(A4),A5
  2812.         move.l        _GfxBase(A4),A6
  2813.  
  2814. ;   Set or clear HIGHITEM flag
  2815.         bclr        #HIGHITEM_B0+8,D4
  2816.  
  2817. ;   Mode = !Mode
  2818.         moveq.l     #1,D1
  2819.         addq.w        #1,D0
  2820.         and.w        D1,D0
  2821.  
  2822. ;   !Mode = HIGHLIGHTOFF ?
  2823.         beq        2$           * Yes
  2824.  
  2825.         bset        #HIGHITEM_B0+8,D4
  2826.  
  2827. 2$        move.w        D4,mi_Flags(A3)
  2828. ***********************************************
  2829. * D0 = !Mode              A0 = Window     *
  2830. * D4 = Window.Current.Flags   A2 = Window     *
  2831. *                  A3 = Item       *
  2832. *                  A5 = Rp          *
  2833. *                  A6 = GfxBase    *
  2834. ***********************************************
  2835.         and.w         #HIGHFLAGS,D4
  2836.         bne         NotHighImage
  2837.  
  2838. ;   DrawMenuItem(Window, Item, !Mode);
  2839. HighImage:    move.l         A3,A1
  2840.         call         DrawMenuItem
  2841.         bra         HighlightDone
  2842.  
  2843. ;   SetDrMd(COMPLEMENT)
  2844. NotHighImage:    moveq.l      #RP_COMPLEMENT,D0
  2845.         move.l         A5,A1
  2846.         libcall      SetDrMd
  2847.  
  2848. ;   Left   = Item->LeftEdge - Window->LeftValue
  2849.         move.w         mi_LeftEdge(A3),D0
  2850.         sub.w         wwd_LeftValue(A2),D0
  2851.         ext.l         D0
  2852.  
  2853. ;   Right  = Left + Item->Width - 1
  2854.         move.l         D0,D2
  2855.         add.w         mi_Width(A3),D2
  2856.         subq.l         #1,D2
  2857.  
  2858. ;   Top    = Item->TopEdge - Window->TopValue
  2859.         move.w         mi_TopEdge(A3),D1
  2860.         sub.w         wwd_TopValue(A2),D1
  2861.         ext.l         D1
  2862.  
  2863. ;   Bottom = Top + Item->Height - 1
  2864.         move.l         D1,D3
  2865.         add.w         mi_Height(A3),D3
  2866.         subq.l         #1,D3
  2867.  
  2868.         move.l         A5,A1
  2869.  
  2870. ***********************************
  2871. * D0 = Left              *
  2872. * D1 = Top              *
  2873. * D2 = Right              *
  2874. * D3 = Bottom       A5 = Rp      *
  2875. * D4 = HighFlags   A6 = GfxBase   *
  2876. ***********************************
  2877. ;   Check out kind of highlighting.
  2878.         cmp.w         #HIGHBOX,D4
  2879.         beq         HighBox
  2880.         cmp.w         #HIGHCOMP,D4
  2881.         bne         HighlightDone
  2882.  
  2883. ;   RectFill(Left, Top, Right, Bottom)
  2884. HighComp:    libcall      RectFill
  2885.         bra         HighlightDone
  2886.  
  2887. ;   DrawRect(Left-4, Top-2, Right + 4, Bottom + 2)
  2888. HighBox:    subq.l         #4,D0
  2889.         subq.l         #2,D1
  2890.         addq.l         #4,D2
  2891.         addq.l         #2,D3
  2892.         bsr         DrawRect
  2893.         bsr         DrawRect
  2894.  
  2895. ;   return TRUE
  2896. HighlightDone:    moveq.l      #TRUE,D0
  2897. HighLightQuit:    movem.l      (SP)+,D2-D4/A2/A3/A5/A6
  2898.         rts
  2899.  
  2900. *********************************************
  2901. * VOID ToggleMenu(Number,Menu)              *
  2902. *                        *
  2903. * Input:                    *
  2904. *   Number.w -    Menu to highlight.        *
  2905. *   Menu   - Pointer to the Menu structure. *
  2906. * Output:                    *
  2907. *   none                    *
  2908. *********************************************
  2909. @ToggleMenu:    movem.l     D2/D3/A6,-(SP)
  2910.  
  2911. ;   Menu enabled ?
  2912.         moveq.l     #MENUENABLED,D2
  2913.         and.w        mu_Flags(A0),D2
  2914.         beq        ToggleDone
  2915.  
  2916.         move.w        D0,D3
  2917.  
  2918. ;   Set drawmode = COMPLEMENT.
  2919.         move.l        _GfxBase(A4),A6
  2920.         lea        _Rp(A4),A1
  2921.         moveq.l     #RP_COMPLEMENT,D0
  2922.         libcall     SetDrMd
  2923.  
  2924. ;   Invert menu.
  2925. ;   Bottom = Number * MenuTextHeight + MenuWindow.TopEdge.
  2926.         move.w        _MenuTextHeight(A4),D2
  2927.         mulu.w        D2,D3
  2928.         add.w        _MenuWindow+wwd_TopEdge(A4),D3
  2929.  
  2930. ;   Top = Bottom - MenuTextHeight + HBORDERSIZE.
  2931.         move.l        D3,D1
  2932.         sub.l        D2,D1
  2933.         addq.l        #HBORDERSIZE,D1
  2934.  
  2935. ;   Left = MenuWindow.leftEdge + VBORDERSIZE.
  2936.         moveq.l     #VBORDERSIZE,D0
  2937.         add.w        _MenuWindow+wwd_LeftEdge(A4),D0
  2938.  
  2939. ;   Right = MenuWindow.RightEdge - VBORDERSIZE.
  2940.         move.w        _MenuWindow+wwd_RightEdge(A4),D2
  2941.         subq.l        #VBORDERSIZE,D2
  2942.  
  2943. ;   RectFill(Rp,Left,Top,Right,Bottom)
  2944.         lea        _Rp(A4),A1
  2945.         libcall     RectFill
  2946.  
  2947. ToggleDone:    movem.l     (SP)+,D2/D3/A6
  2948.         rts
  2949.  
  2950. *******************************************************
  2951. * VOID DrawAllMenus(Window)                           *
  2952. *                              *
  2953. * Input:                          *
  2954. *   Window  - Window to draw into (may be itemwindow) *
  2955. * Output:                          *
  2956. *   none                          *
  2957. *******************************************************
  2958. @DrawAllMenus:    movem.l     D2-D5/A2/A3/A5/A6,-(SP)
  2959.  
  2960. ;   MenuLeft = Window.leftEdge + VBORDERSIZE
  2961.         moveq.l     #VBORDERSIZE,D5
  2962.         add.w        wwd_LeftEdge(A0),D5                ; 4.0
  2963.  
  2964. ;   MenuTop = Window.TopEdge + HBORDERSIZE+1  [+1 here instead of TxBaseline+1 later]
  2965.         moveq.l     #HBORDERSIZE+1,D4
  2966.         add.w        wwd_TopEdge(A0),D4                 ; 4.0
  2967.  
  2968. ;   MenuRight = Window.RightEdge - VBORDERSIZE
  2969.         move.w        wwd_RightEdge(A0),D2               ; 4.0
  2970.         subq.w        #VBORDERSIZE,D2
  2971.         ext.l        D2
  2972.  
  2973. ;   MenuSortedT = MenuSorted;
  2974.         lea        _MenuSorted(A4),A3
  2975.         lea        _Rp(A4),A5
  2976.         move.l        _GfxBase(A4),A6
  2977.  
  2978. ****************************************
  2979. * D2 = MenuRight               *
  2980. * D4 = MenuTop         A3 = MenuSortedT  *
  2981. * D5 = MenuLeft      A5 = Rp           *
  2982. *             A6 = GfxBase      *
  2983. ****************************************
  2984. NextMenu:    move.l        (A3)+,A2
  2985.  
  2986. ;   SetAPen(Rp,DetailPen)
  2987.         moveq.l     #0,D0
  2988.         move.b        _DetailPen(A4),D0
  2989.         move.l        A5,A1
  2990.         libcall     SetAPen
  2991.  
  2992. ;   Move(Rp, MenuLeft, MenuTop + Rp.TxBaseline)
  2993.         move.l        D5,D0
  2994.         move.l        D4,D1
  2995.         add.w        _Rp+rp_TxBaseline(A4),D1    * 4.4
  2996.         move.l        A5,A1
  2997.         libcall     Move
  2998.  
  2999. ;   Text(Rp,(*MenuSortedT)->MenuName,Mystrlen((*MenuSortedT)->MenuName))
  3000.         move.l        mu_MenuName(A2),A0
  3001.         call        Mystrlen
  3002.         move.l        A5,A1
  3003.         move.l        mu_MenuName(A2),A0
  3004.         libcall     Text
  3005.  
  3006. ;   NextMenuTop = MenuTop + MenuTextHeight
  3007.         move.l        D4,D3
  3008.         add.w        _MenuTextHeight(A4),D3
  3009.  
  3010. ;   GhostItem ?
  3011.         moveq.l     #MENUENABLED,D0
  3012.         and.w        mu_Flags(A2),D0
  3013.         bne        NoMenuGhost
  3014.  
  3015. ;   SetAfPt(Rp, GhostPattern, 1)
  3016.         lea        GhostPattern(PC),A0
  3017.         move.l        A0,_Rp+rp_AreaPtrn(A4)
  3018.  
  3019.         moveq.l     #1,D0
  3020.         move.b        D0,_Rp+rp_AreaPtSz(A4)
  3021.  
  3022. ;   SetAPen(Rp,BlockPen)
  3023.         move.b        _BlockPen(A4),D0
  3024.         move.l        A5,A1
  3025.         libcall     SetAPen
  3026.  
  3027. ;   RectFill(Rp,MenuLeft,MenuTop + HBORDERSIZE,MenuRight,NextMenuTop)
  3028.         move.l        D5,D0
  3029.         move.l        D4,D1
  3030.         addq.w        #HBORDERSIZE,D1
  3031.         move.l        A5,A1
  3032.         libcall     RectFill
  3033.  
  3034. ;   SetAfPt(&Rp,NormalPattern,1);
  3035.         lea        NormalPattern(PC),A0
  3036.         move.l        A0,_Rp+rp_AreaPtrn(A4)
  3037.  
  3038. ;   MenuTop = NextMenuTop
  3039. NoMenuGhost:    move.l        D3,D4
  3040.  
  3041. ;   More menus ?
  3042.         move.l        (A3),D0
  3043.         bne        NextMenu
  3044.  
  3045.         movem.l     (SP)+,D2-D5/A2/A3/A5/A6
  3046.         rts
  3047.  
  3048. ;*******************************************************
  3049. ;* ULONG Mystrlen(String) - A short (and fast) strlen. *
  3050. ;*                               *
  3051. ;* Input:                           *
  3052. ;*   String   - pointer to a null-terminated string.   *
  3053. ;* Output:                           *
  3054. ;*   return   - length of string. max 32767 chars      *
  3055. ;*******************************************************
  3056. @Mystrlen:    moveq.l     #-1,D0
  3057. 1$        tst.b        (A0)+
  3058.         dbeq        D0,1$
  3059.         neg.l        D0
  3060.         subq.l        #1,D0
  3061.         rts
  3062.  
  3063. **********************************************
  3064. * DrawRect(Rp,Left+2,Top+1,Right-2,Bottom-1) *
  3065. *       A1    D0   D1     D2         D3      *
  3066. * A6 = GfxBase, A1 not destroyed         *
  3067. **********************************************
  3068. DrawRect:    movem.l     D4/D5/A2,-(SP)
  3069.  
  3070.         move.l        D0,D4
  3071.         move.l        D1,D5
  3072.         move.l        A1,A2
  3073.  
  3074. ;   Move(Rp,Left,Top)
  3075.         libcall     Move
  3076.  
  3077. ;   Draw(Rp,Left++,Bottom)
  3078.         move.l        D4,D0
  3079.         move.l        D3,D1
  3080.         move.l        A2,A1
  3081.         libcall     Draw
  3082.         addq.l        #1,D4
  3083.  
  3084. ;   Draw(Rp,Right,Bottom--)
  3085.         move.l        D2,D0
  3086.         move.l        D3,D1
  3087.         move.l        A2,A1
  3088.         libcall     Draw
  3089.         subq.l        #1,D3
  3090.  
  3091. ;   Draw(Rp,Right--,Top)
  3092.         move.l        D2,D0
  3093.         move.l        D5,D1
  3094.         move.l        A2,A1
  3095.         libcall     Draw
  3096.         subq.l        #1,D2
  3097.  
  3098. ;   Draw(Rp,Left,Top++)
  3099.         move.l        D4,D0
  3100.         move.l        D5,D1
  3101.         move.l        A2,A1
  3102.         libcall     Draw
  3103.         addq.l        #1,D5
  3104.  
  3105. ;   Draw(Rp,Left++,Bottom)
  3106.         move.l        D4,D0
  3107.         move.l        D3,D1
  3108.         move.l        A2,A1
  3109.         libcall     Draw
  3110.         addq.l        #1,D4
  3111.  
  3112. ;   Move(Rp,Right,Bottom)
  3113.         move.l        D2,D0
  3114.         move.l        D3,D1
  3115.         move.l        A2,A1
  3116.         libcall     Move
  3117.  
  3118. ;   Draw(Rp,Right--,Top)
  3119.         move.l        D2,D0
  3120.         move.l        D5,D1
  3121.         move.l        A2,A1
  3122.         libcall     Draw
  3123.         subq.l        #1,D2
  3124.  
  3125.         move.l        D4,D0
  3126.         move.l        D5,D1
  3127.         move.l        A2,A1
  3128.         movem.l     (SP)+,D4/D5/A2
  3129.         rts
  3130.  
  3131. ; Put these images in the code segment
  3132. MyAmigaKeyImage:
  3133.         dc.w        -25,0          ; ig_LeftEdge, ig_TopEdge
  3134.         dc.w        23,AMIGAKEYHEIGHT ; ig_Width, ig_Height
  3135.         dc.w        1              ; ig_Depth
  3136.         dc.l        AmigaKeyHighRes   ; ig_ImageData
  3137.         dc.b        1,0           ; ig_PlanePick, ig_PlaneOnOff
  3138.         dc.l        NULL          ; ig_NextImage
  3139.  
  3140.         dc.w        -16,0          ; ig_LeftEdge, ig_TopEdge
  3141.         dc.w        14,AMIGAKEYHEIGHT ; ig_Width, ig_Height
  3142.         dc.w        1              ; ig_Depth
  3143.         dc.l        AmigaKeyLoRes     ; ig_ImageData
  3144.         dc.b        1,0           ; ig_PlanePick, ig_PlaneOnOff
  3145.         dc.l        NULL          ; ig_NextImage
  3146.  
  3147. GhostPattern:    dc.w        %0001000100010001
  3148.         dc.w        %0100010001000100
  3149.  
  3150. NormalPattern:    dc.w        %1111111111111111
  3151.         dc.w        %1111111111111111
  3152.  
  3153.         section     ImageData,DATA,CHIP
  3154. AmigaKeyHighRes:
  3155.         dc.l        %11000000000000000000011000000000
  3156.         dc.l        %00000000000000111100000000000000
  3157.         dc.l        %00000000000011111100000000000000
  3158.         dc.l        %00000000001110011100000000000000
  3159.         dc.l        %00000000111000011100000000000000
  3160.         dc.l        %00000011111111111100000000000000
  3161.         dc.l        %00011111100000111111000000000000
  3162.         dc.l        %11000000000000000000011000000000
  3163.  
  3164. AmigaKeyLoRes:    dc.w        %1000000000000100
  3165.         dc.w        %0000000011100000
  3166.         dc.w        %0000000111100000
  3167.         dc.w        %0000001101100000
  3168.         dc.w        %0000011001100000
  3169.         dc.w        %0000111111100000
  3170.         dc.w        %0011110011110000
  3171.         dc.w        %1000000000000100
  3172.  
  3173. AMIGAKEYHEIGHT    equ        (*-AmigaKeyLoRes)/2
  3174.  
  3175.         end
  3176.  
  3177.  
  3178.